<pre class='metadata'>
Group: WHATWG
H1: DOM
Shortname: dom
Text Macro: TWITTER thedomstandard
Abstract: DOM defines a platform-neutral model for events, aborting activities, and node trees.
Translation: ja https://triple-underscore.github.io/DOM4-ja.html
Ignored Terms: EmptyString, Array, Document
Indent: 1
</pre>

<pre class=anchors>
urlPrefix: https://www.w3.org/TR/xml/#NT-
 type: type
  text: Name; url: Name
  text: Char; url: Char
  text: PubidChar; url: PubidChar
urlPrefix: https://www.w3.org/TR/xml-names/#NT-
 type: type
  text: QName; url: QName
url: https://w3c.github.io/DOM-Parsing/#dfn-createcontextualfragment-fragment
 type: method; text: createContextualFragment(); for: Range
type: interface
 url: https://w3c.github.io/touch-events/#idl-def-touchevent
  text: TouchEvent
 url: https://w3c.github.io/deviceorientation/spec-source-orientation.html#devicemotion
  text: DeviceMotionEvent
  text: DeviceOrientationEvent
 url: https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15
  text: WebGLContextEvent
urlPrefix: https://tc39.github.io/ecma262/#; spec: ECMASCRIPT
 text: Construct; url: sec-construct; type: abstract-op
 type: dfn
  text: Realm; url: realm
  text: surrounding agent; url: surrounding-agent
urlPrefix: https://w3c.github.io/hr-time/#; spec: HR-TIME
 type:typedef; urlPrefix: dom-; text: DOMHighResTimeStamp
 type:dfn; text: time origin; url: dfn-time-origin
 type:dfn; text: clock resolution
</pre>

<pre class=link-defaults>
spec:html; type:element
 text: title
 text: script
spec:infra; type:dfn; text:list
</pre>

<h2 id=goals class=no-num>Goals</h2>

This specification standardizes the DOM. It does so as follows:

<ol>
 <li>
  <p>By consolidating <cite>DOM Level 3 Core</cite> [[DOM-Level-3-Core]],
  <cite>Element Traversal</cite> [[ELEMENTTRAVERSAL]],
  <cite>Selectors API Level 2</cite> [[SELECTORS-API2]], the
  "DOM Event Architecture" and "Basic Event Interfaces" chapters of
  <cite>DOM Level 3 Events</cite> [[uievents-20031107]] (specific types of events do not
  belong in the DOM Standard), and <cite>DOM Level 2 Traversal and Range</cite>
  [[DOM-Level-2-Traversal-Range]], and:

  <ul class=brief>
   <li>Aligning them with the JavaScript ecosystem where possible.
   <li>Aligning them with existing implementations.
   <li>Simplifying them as much as possible.
  </ul>

 <li><p>By moving features from the HTML Standard [[!HTML]] that make more sense to be
 specified as part of the DOM Standard.

 <li>
  <p>By defining a replacement for the "Mutation Events" and
  "Mutation Name Event Types" chapters of <cite>DOM Level 3 Events</cite>
  [[uievents-20031107]] as the old model
  was problematic.

  <p class="note no-backref">The old model is expected to be removed from implementations
  in due course.

 <li><p>By defining new features that simplify common DOM operations.
</ol>


<h2 id=infrastructure oldids=terminology,dependencies>Infrastructure</h2>

<p>This specification depends on the Infra Standard. [[!INFRA]]

<p>Some of the terms used in this specification are defined in <cite>Encoding</cite>,
<cite>Selectors</cite>, <cite>Web IDL</cite>, <cite>XML</cite>, and <cite>Namespaces in XML</cite>.
[[!ENCODING]]
[[!SELECTORS4]]
[[!WEBIDL]]
[[!XML]]
[[!XML-NAMES]]

<p>The term <dfn export>context object</dfn> means the object on which the algorithm,
attribute getter, attribute setter, or method being discussed was called.

<p>When extensions are needed, the DOM Standard can be updated accordingly, or a new standard
can be written that hooks into the provided extensibility hooks for
<dfn export lt="other applicable specifications">applicable specifications</dfn>.
<!-- https://www.w3.org/mid/17E341CD-E790-422C-9F9A-69347EE01CEB@iki.fi -->


<h3 id=trees>Trees</h3> <!-- Sorry reddit, this is not /r/trees -->

<p>A <dfn export id=concept-tree>tree</dfn> is a finite hierarchical tree structure. In
<dfn export id=concept-tree-order>tree order</dfn> is preorder, depth-first traversal of a
<a>tree</a>.
<!-- https://en.wikipedia.org/wiki/Depth-first_search -->

<p>An object that
<dfn export for=tree id=concept-tree-participate lt="participate|participate in a tree|participates in a tree">participates</dfn>
in a <a>tree</a> has a <dfn export for=tree id=concept-tree-parent>parent</dfn>, which is either
null or an object, and has
<dfn export for=tree id=concept-tree-child lt="child|children">children</dfn>, which is an
<a>ordered set</a> of objects. An object <var>A</var> whose <a for=tree>parent</a> is object
<var>B</var> is a <a for=tree>child</a> of <var>B</var>.

<p>The <dfn export for=tree id=concept-tree-root>root</dfn> of an object is itself, if its
<a for=tree>parent</a> is null, or else it is the <a for=tree>root</a> of its
<a for=tree>parent</a>. The <a for=tree>root</a> of a <a>tree</a> is any object
<a for=tree>participating</a> in that <a>tree</a> whose <a for=tree>parent</a> is null.

An object <var>A</var> is called a
<dfn export for=tree id=concept-tree-descendant>descendant</dfn> of an object
<var>B</var>, if either <var>A</var> is a
<a for=tree>child</a> of <var>B</var> or
<var>A</var> is a <a for=tree>child</a> of an
object <var ignore>C</var> that is a
<a>descendant</a> of <var>B</var>.

An
<dfn export for=tree id=concept-tree-inclusive-descendant>inclusive descendant</dfn> is
an object or one of its
<a>descendants</a>.

An object <var>A</var> is called an
<dfn export for=tree id=concept-tree-ancestor>ancestor</dfn> of an object
<var>B</var> if and only if <var>B</var> is a
<a>descendant</a> of
<var>A</var>.

An <dfn export for=tree id=concept-tree-inclusive-ancestor>inclusive ancestor</dfn> is
an object or one of its <a>ancestors</a>.

An object <var>A</var> is called a
<dfn export for=tree id=concept-tree-sibling>sibling</dfn> of an object
<var>B</var>, if and only if <var>B</var> and <var>A</var>
share the same non-null <a for=tree>parent</a>.

An <dfn export for=tree id=concept-tree-inclusive-sibling>inclusive sibling</dfn> is an
object or one of its <a for=tree>siblings</a>.

An object <var>A</var> is
<dfn export for=tree id=concept-tree-preceding>preceding</dfn> an object
<var>B</var> if <var>A</var> and <var>B</var> are in the
same <a>tree</a> and <var>A</var> comes
before <var>B</var> in
<a>tree order</a>.

An object <var>A</var> is
<dfn export for=tree id=concept-tree-following>following</dfn> an object
<var>B</var> if <var>A</var> and <var>B</var> are in the
same <a>tree</a> and <var>A</var> comes
after <var>B</var> in
<a>tree order</a>.

The <dfn export for=tree id=concept-tree-first-child>first child</dfn> of an object is its
first <a for=tree>child</a> or null if it has no <a>children</a>.

The <dfn export for=tree id=concept-tree-last-child>last child</dfn> of an object is its
last <a for=tree>child</a> or null if it has no <a>children</a>.

The <dfn export for=tree id=concept-tree-previous-sibling>previous sibling</dfn> of an
object is its first <a>preceding</a>
<a for=tree>sibling</a> or null if it has no
<a>preceding</a>
<a for=tree>sibling</a>.

The <dfn export for=tree id=concept-tree-next-sibling>next sibling</dfn> of an
object is its first <a>following</a>
<a for=tree>sibling</a> or null if it has no
<a>following</a>
<a for=tree>sibling</a>.

<p>The <dfn export for=tree id=concept-tree-index>index</dfn> of an object is its number of
<a>preceding</a> <a for=tree>siblings</a>, or 0 if it has none.


<h3 id="ordered-sets">Ordered sets</h3>

<p>The <dfn export id=concept-ordered-set-parser>ordered set parser</dfn> takes a string
<var>input</var> and then runs these steps:

<ol>
 <li><p>Let <var>inputTokens</var> be the result of
 <a lt="split on ASCII whitespace">splitting <var>input</var> on ASCII whitespace</a>.

 <li><p>Let <var>tokens</var> be a new <a>ordered set</a>.

 <li><p><a for=list>For each</a> <var>token</var> in <var>inputTokens</var>, <a for=set>append</a>
 <var>token</var> to <var>tokens</var>.

 <li>Return <var>tokens</var>.
</ol>

<p>The <dfn export id=concept-ordered-set-serializer>ordered set serializer</dfn> takes a
<var>set</var> and returns the <a for=string>concatenation</a> of <var>set</var> using U+0020 SPACE.


<h3 id=selectors>Selectors</h3>

<!--
To <dfn export>match a relative selectors string</dfn> <var>relativeSelectors</var>
against a <var>set</var>, run these steps:

<ol>
 <li>Let <var>s</var> be the result of
 <a>parse a relative selector</a> from
 <var>relativeSelectors</var> against <var>set</var>.
 [[!SELECTORS4]]

 <li>If <var>s</var> is failure, <a>throw</a> a "{{SyntaxError!!exception}}" {{DOMException}}.

 <li>Return the result of <a>evaluate a selector</a> <var>s</var>
  using <a>:scope elements</a> <var>set</var>. [[!SELECTORS4]]
</ol>
-->

<p>To <dfn export>scope-match a selectors string</dfn> <var>selectors</var> against a
<var>node</var>, run these steps:

<ol>
 <li><p>Let <var>s</var> be the result of <a>parse a selector</a> <var>selectors</var>.
 [[!SELECTORS4]]

 <li><p>If <var>s</var> is failure, then <a>throw</a> a "{{SyntaxError!!exception}}"
 {{DOMException}}.

 <li><p>Return the result of <a>match a selector against a tree</a> with <var>s</var> and
 <var>node</var>'s <a for=tree>root</a> using <a>scoping root</a> <var>node</var>. [[!SELECTORS4]].
</ol>

<p class=note>Support for namespaces within selectors is not planned and will not be
added.


<h3 id=namespaces>Namespaces</h3>

<p>To <dfn export>validate</dfn> a <var>qualifiedName</var>, <a>throw</a> an
"{{InvalidCharacterError!!exception}}" {{DOMException}} if <var>qualifiedName</var> does not match
the <code><a type>Name</a></code> or <code><a type>QName</a></code> production.

To <dfn export>validate and extract</dfn> a <var>namespace</var> and <var>qualifiedName</var>,
run these steps:

<ol>
 <li>If <var>namespace</var> is the empty string, set it to null.

 <li><a>Validate</a> <var>qualifiedName</var>.

 <li>Let <var>prefix</var> be null.

 <li>Let <var>localName</var> be <var>qualifiedName</var>.

 <li>If <var>qualifiedName</var> contains a "<code>:</code>" (U+003E), then split the
 string on it and set <var>prefix</var> to the part before and <var>localName</var> to
 the part after.

 <li>If <var>prefix</var> is non-null and <var>namespace</var> is null, then <a>throw</a> a
 "{{NamespaceError!!exception}}" {{DOMException}}.

 <li>If <var>prefix</var> is "<code>xml</code>" and <var>namespace</var> is not the
 <a>XML namespace</a>, then <a>throw</a> a "{{NamespaceError!!exception}}" {{DOMException}}.

 <li>If either <var>qualifiedName</var> or <var>prefix</var> is
 "<code>xmlns</code>" and <var>namespace</var> is not the
 <a>XMLNS namespace</a>, then <a>throw</a> a
 "{{NamespaceError!!exception}}" {{DOMException}}.

 <li>If <var>namespace</var> is the <a>XMLNS namespace</a> and neither <var>qualifiedName</var>
 nor <var>prefix</var> is "<code>xmlns</code>", then <a>throw</a> a "{{NamespaceError!!exception}}"
 {{DOMException}}.

 <li>Return <var>namespace</var>, <var>prefix</var>, and <var>localName</var>.
</ol>



<h2 id=events>Events</h2>

<h3 id=introduction-to-dom-events>Introduction to "DOM Events"</h3>

Throughout the web platform <a>events</a> are <a>dispatched</a> to objects to signal an
occurrence, such as network activity or user interaction. These objects implement the
{{EventTarget}} interface and can therefore add <a>event listeners</a> to observe
<a>events</a> by calling {{EventTarget/addEventListener()}}:

<pre class=lang-javascript>
obj.addEventListener("load", imgFetched)

function imgFetched(ev) {
  // great success
  &hellip;
}
</pre>

<a>Event listeners</a> can be removed
by utilizing the
{{EventTarget/removeEventListener()}}
method, passing the same arguments.

<a>Events</a> are objects too and implement the
{{Event}} interface (or a derived interface). In the example above
<var ignore>ev</var> is the <a>event</a>. <var ignore>ev</var> is
passed as an argument to the
<a>event listener</a>'s <a for="event listener">callback</a>
(typically a JavaScript Function as shown above).
<a>Event listeners</a> key off the
<a>event</a>'s
{{Event/type}} attribute value
("<code>load</code>" in the above example). The
<a>event</a>'s
{{Event/target}} attribute value returns the
object to which the <a>event</a> was
<a>dispatched</a>
(<var ignore>obj</var> above).

<p id="synthetic-events">Although <a>events</a> are typically <a>dispatched</a> by the user agent
as the result of user interaction or the completion of some task, applications can <a>dispatch</a>
<a>events</a> themselves by using what are commonly known as synthetic events:

<pre class='lang-javascript'>
// add an appropriate event listener
obj.addEventListener("cat", function(e) { process(e.detail) })

// create and dispatch the event
var event = new CustomEvent("cat", {"detail":{"hazcheeseburger":true}})
obj.dispatchEvent(event)
</pre>

Apart from signaling, <a>events</a> are
sometimes also used to let an application control what happens next in an
operation. For instance as part of form submission an
<a>event</a> whose
{{Event/type}} attribute value is
"<code>submit</code>" is
<a>dispatched</a>. If this
<a>event</a>'s
{{Event/preventDefault()}} method is
invoked, form submission will be terminated. Applications who wish to make
use of this functionality through <a>events</a>
<a>dispatched</a> by the application
(synthetic events) can make use of the return value of the
{{EventTarget/dispatchEvent()}} method:

<pre class='lang-javascript'>
if(obj.dispatchEvent(event)) {
  // event was not canceled, time for some magic
  &hellip;
}
</pre>

When an <a>event</a> is
<a>dispatched</a> to an object that
<a>participates</a> in a
<a>tree</a> (e.g. an
<a for="/">element</a>), it can reach
<a>event listeners</a> on that object's
<a>ancestors</a> too. First all object's
<a>ancestor</a>
<a>event listeners</a> whose
<a for="event listener">capture</a> variable is set to true are invoked, in
<a>tree order</a>. Second, object's own
<a>event listeners</a> are invoked. And
finally, and only if <a>event</a>'s
{{Event/bubbles}} attribute value is true,
object's  <a>ancestor</a>
<a>event listeners</a> are invoked again,
but now in reverse <a>tree order</a>.

Let's look at an example of how <a>events</a> work in a <a>tree</a>:

<pre class='lang-markup'>
&lt;!doctype html>
&lt;html>
 &lt;head>
  &lt;title>Boring example&lt;/title>
 &lt;/head>
 &lt;body>
  &lt;p>Hello &lt;span id=x>world&lt;/span>!&lt;/p>
  &lt;script>
   function test(e) {
     debug(e.target, e.currentTarget, e.eventPhase)
   }
   document.addEventListener("hey", test, {capture: true})
   document.body.addEventListener("hey", test)
   var ev = new Event("hey", {bubbles:true})
   document.getElementById("x").dispatchEvent(ev)
  &lt;/script>
 &lt;/body>
&lt;/html>
</pre>

The <code>debug</code> function will be invoked twice. Each time the <a>event</a>'s
{{Event/target}} attribute value will be the
<code>span</code> <a for="/">element</a>. The
first time {{Event/currentTarget}} attribute's
value will be the <a>document</a>, the second
time the <code>body</code> <a for="/">element</a>.
{{Event/eventPhase}} attribute's value
switches from {{Event/CAPTURING_PHASE}}
to {{Event/BUBBLING_PHASE}}. If an
<a>event listener</a> was registered for
the <code>span</code> <a for="/">element</a>,
{{Event/eventPhase}} attribute's value
would have been {{Event/AT_TARGET}}.


<h3 id=interface-event>Interface {{Event}}</h3>

<pre class="idl">
[Exposed=(Window,Worker,AudioWorklet)]
interface Event {
  constructor(DOMString type, optional EventInit eventInitDict = {});

  readonly attribute DOMString type;
  readonly attribute EventTarget? target;
  readonly attribute EventTarget? srcElement; // historical
  readonly attribute EventTarget? currentTarget;
  sequence&lt;EventTarget> composedPath();

  const unsigned short NONE = 0;
  const unsigned short CAPTURING_PHASE = 1;
  const unsigned short AT_TARGET = 2;
  const unsigned short BUBBLING_PHASE = 3;
  readonly attribute unsigned short eventPhase;

  void stopPropagation();
           attribute boolean cancelBubble; // historical alias of .stopPropagation
  void stopImmediatePropagation();

  readonly attribute boolean bubbles;
  readonly attribute boolean cancelable;
           attribute boolean returnValue;  // historical
  void preventDefault();
  readonly attribute boolean defaultPrevented;
  readonly attribute boolean composed;

  [Unforgeable] readonly attribute boolean isTrusted;
  readonly attribute DOMHighResTimeStamp timeStamp;

  void initEvent(DOMString type, optional boolean bubbles = false, optional boolean cancelable = false); // historical
};

dictionary EventInit {
  boolean bubbles = false;
  boolean cancelable = false;
  boolean composed = false;
};
</pre>

<p>An {{Event}} object is simply named an <dfn export id=concept-event>event</dfn>. It allows for
signaling that something has occurred, e.g., that an image has completed downloading.</p>

<p>A <dfn export>potential event target</dfn> is null or an {{EventTarget}} object.

<p>An <a>event</a> has an associated <dfn export for=Event>target</dfn> (a
<a>potential event target</a>). Unless stated otherwise it is null.

<p>An <a>event</a> has an associated <dfn export for=Event>relatedTarget</dfn> (a
<a>potential event target</a>). Unless stated otherwise it is null.

<p class=note>Other specifications use <a for=Event>relatedTarget</a> to define a
<code>relatedTarget</code> attribute. [[UIEVENTS]]

<p>An <a>event</a> has an associated <dfn export for=Event>touch target list</dfn> (a
<a for=/>list</a> of zero or more <a>potential event targets</a>). Unless stated otherwise it is the
empty list.

<p class=note>The <a for=Event>touch target list</a> is for the exclusive use of defining the
{{TouchEvent}} interface and related interfaces. [[TOUCH-EVENTS]]

<p>An <a>event</a> has an associated <dfn export for=Event>path</dfn>. A <a for=Event>path</a> is a
<a for=/>list</a> of <a for=/>structs</a>. Each <a for=/>struct</a> consists of an
<dfn for=Event/path>invocation target</dfn> (an {{EventTarget}} object), an
<dfn for=Event/path>invocation-target-in-shadow-tree</dfn> (a boolean), a
<dfn for=Event/path>shadow-adjusted target</dfn> (a <a>potential event target</a>), a
<dfn id=event-path-relatedtarget for=Event/path>relatedTarget</dfn> (a
<a>potential event target</a>), a <dfn for=Event/path>touch target list</dfn> (a <a for=/>list</a>
of <a>potential event targets</a>), a <dfn for=Event/path>root-of-closed-tree</dfn> (a boolean), and
a <dfn for=Event/path>slot-in-closed-tree</dfn> (a boolean). A <a for=Event>path</a> is initially
the empty list.</p>

<dl class=domintro>
 <dt><code><var>event</var> = new <a constructor lt="Event()">Event</a>(<var>type</var> [, <var>eventInitDict</var>])</code>
 <dd>Returns a new <var>event</var> whose
 {{Event/type}} attribute value is set to
 <var>type</var>. The <var>eventInitDict</var> argument
 allows for setting the {{Event/bubbles}} and
 {{Event/cancelable}} attributes via object
 members of the same name.

 <dt><code><var>event</var> . {{Event/type}}</code>
 <dd>Returns the type of <var>event</var>, e.g.
 "<code>click</code>", "<code>hashchange</code>", or
 "<code>submit</code>".

 <dt><code><var>event</var> . {{Event/target}}</code>
 <dd>Returns the object to which <var>event</var> is <a>dispatched</a> (its
 <a for=Event>target</a>).

 <dt><code><var>event</var> . {{Event/currentTarget}}</code>
 <dd>Returns the object whose <a>event listener</a>'s <a for="event listener">callback</a> is currently being
 invoked.

 <dt><code><var>event</var> . {{Event/composedPath()}}</code>
 <dd>Returns the <a for=Event/path>invocation target</a> objects of <var>event</var>'s
 <a for=Event>path</a> (objects on which listeners will be invoked), except for any
 <a for=/>nodes</a> in <a for=/>shadow trees</a> of which the <a for=/>shadow root</a>'s
 <a for=ShadowRoot>mode</a> is "<code>closed</code>" that are not reachable from <var>event</var>'s
 {{Event/currentTarget}}.

 <dt><code><var>event</var> . {{Event/eventPhase}}</code>
 <dd>Returns the <a>event</a>'s phase, which is one of {{Event/NONE}},
 {{Event/CAPTURING_PHASE}},
 {{Event/AT_TARGET}}, and
 {{Event/BUBBLING_PHASE}}.

 <dt><code><var>event</var> . <a method for=Event lt="stopPropagation()">stopPropagation</a>()</code>
 <dd>When <a>dispatched</a> in a <a>tree</a>, invoking this method prevents
 <var>event</var> from reaching any objects other than the current object.

 <dt><code><var>event</var> . <a method for=Event lt="stopImmediatePropagation()">stopImmediatePropagation</a>()</code>
 <dd>Invoking this method prevents <var>event</var> from reaching
 any registered <a>event listeners</a> after the current one finishes running and, when
 <a>dispatched</a> in a <a>tree</a>, also prevents <var>event</var> from reaching any
 other objects.

 <dt><code><var>event</var> . {{Event/bubbles}}</code>
 <dd>Returns true or false depending on how <var>event</var> was initialized. True if
 <var>event</var> goes through its <a for=Event>target</a>'s <a for=tree>ancestors</a> in reverse
 <a>tree order</a>, and false otherwise.

 <dt><code><var>event</var> . {{Event/cancelable}}</code>
 <dd>Returns true or false depending on how <var>event</var> was initialized. Its return
 value does not always carry meaning, but true can indicate that part of the operation
 during which <var>event</var> was <a>dispatched</a>, can be canceled by invoking the
 {{Event/preventDefault()}} method.

 <dt><code><var>event</var> . <a method for=Event lt="preventDefault()">preventDefault</a>()</code>
 <dd>If invoked when the {{Event/cancelable}} attribute value is true, and while executing a
 listener for the <var>event</var> with {{AddEventListenerOptions/passive}} set to false, signals to
 the operation that caused <var>event</var> to be <a>dispatched</a> that it needs to be canceled.

 <dt><code><var>event</var> . {{Event/defaultPrevented}}</code>
 <dd>Returns true if {{Event/preventDefault()}} was invoked successfully to indicate cancelation,
 and false otherwise.

 <dt><code><var>event</var> . {{Event/composed}}</code>
 <dd>Returns true or false depending on how <var>event</var> was initialized. True if
 <var>event</var> invokes listeners past a {{ShadowRoot}} <a>node</a> that is the
 <a for=tree>root</a> of its <a for=Event>target</a>, and false otherwise.

 <dt><code><var>event</var> . {{Event/isTrusted}}</code>
 <dd>Returns true if <var>event</var> was
 <a>dispatched</a> by the user agent, and
 false otherwise.

 <dt><code><var>event</var> . {{Event/timeStamp}}</code>
 <dd>Returns the <var>event</var>'s timestamp as the number of milliseconds measured relative to
 the <a>time origin</a>.
</dl>

<p>The <dfn attribute for=Event><code>type</code></dfn> attribute must return the value it was
initialized to. When an <a>event</a> is created the attribute must be initialized to the empty
string.

<p>The <dfn attribute for=Event><code>target</code></dfn> attribute's getter, when invoked, must
return the <a>context object</a>'s <a for=Event>target</a>.

<p>The <dfn attribute for=Event><code>srcElement</code></dfn> attribute's getter, when invoked, must
return the <a>context object</a>'s <a for=Event>target</a>.

<p>The <dfn attribute for=Event><code>currentTarget</code></dfn> attribute must return the value it
was initialized to. When an <a>event</a> is created the attribute must be initialized to null.

<p>The <dfn method for=Event><code>composedPath()</code></dfn> method, when invoked, must run these
steps:

<ol>
 <li><p>Let <var>composedPath</var> be an empty <a for=/>list</a>.

 <li><p>Let <var>path</var> be the <a>context object</a>'s <a for=Event>path</a>.

 <li><p>If <var>path</var> <a for=list>is empty</a>, then return <var>composedPath</var>.

 <li><p>Let <var>currentTarget</var> be the <a>context object</a>'s {{Event/currentTarget}}
 attribute value.

 <li><p><a for=list>Append</a> <var>currentTarget</var> to <var>composedPath</var>.

 <li><p>Let <var>currentTargetIndex</var> be 0.

 <li><p>Let <var>currentTargetHiddenSubtreeLevel</var> be 0.

 <li><p>Let <var>index</var> be <var>path</var>'s <a for=list>size</a> &minus; 1.

 <li>
  <p>While <var>index</var> is greater than or equal to 0:

  <ol>
   <li><p>If <var>path</var>[<var>index</var>]'s <a for=Event/path>root-of-closed-tree</a> is true,
   then increase <var>currentTargetHiddenSubtreeLevel</var> by 1.

   <li><p>If <var>path</var>[<var>index</var>]'s <a for=Event/path>invocation target</a> is
   <var>currentTarget</var>, then set <var>currentTargetIndex</var> to <var>index</var> and
   <a for=iteration>break</a>.

   <li><p>If <var>path</var>[<var>index</var>]'s <a for=Event/path>slot-in-closed-tree</a> is true,
   then decrease <var>currentTargetHiddenSubtreeLevel</var> by 1.

   <li><p>Decrease <var>index</var> by 1.
  </ol>

 <li><p>Let <var>currentHiddenLevel</var> and <var>maxHiddenLevel</var> be
 <var>currentTargetHiddenSubtreeLevel</var>.

 <li><p>Set <var>index</var> to <var>currentTargetIndex</var> &minus; 1.

 <li>
  <p>While <var>index</var> is greater than or equal to 0:

  <ol>
   <li><p>If <var>path</var>[<var>index</var>]'s <a for=Event/path>root-of-closed-tree</a> is true,
   then increase <var>currentHiddenLevel</var> by 1.

   <li><p>If <var>currentHiddenLevel</var> is less than or equal to <var>maxHiddenLevel</var>, then
   <a for=list>prepend</a> <var>path</var>[<var>index</var>]'s
   <a for=Event/path>invocation target</a> to <var>composedPath</var>.

   <li>
    <p>If <var>path</var>[<var>index</var>]'s <a for=Event/path>slot-in-closed-tree</a> is true,
    then:

    <ol>
     <li><p>Decrease <var>currentHiddenLevel</var> by 1.

     <li><p>If <var>currentHiddenLevel</var> is less than <var>maxHiddenLevel</var>, then set
     <var>maxHiddenLevel</var> to <var>currentHiddenLevel</var>.
    </ol>

   <li><p>Decrease <var>index</var> by 1.
  </ol>

 <li><p>Set <var>currentHiddenLevel</var> and <var>maxHiddenLevel</var> to
 <var>currentTargetHiddenSubtreeLevel</var>.

 <li><p>Set <var>index</var> to <var>currentTargetIndex</var> + 1.

 <li>
  <p>While <var>index</var> is less than <var>path</var>'s <a for=list>size</a>:

  <ol>
   <li><p>If <var>path</var>[<var>index</var>]'s <a for=Event/path>slot-in-closed-tree</a> is true,
   then increase <var>currentHiddenLevel</var> by 1.

   <li><p>If <var>currentHiddenLevel</var> is less than or equal to <var>maxHiddenLevel</var>, then
   <a for=list>append</a> <var>path</var>[<var>index</var>]'s
   <a for=Event/path>invocation target</a> to <var>composedPath</var>.

   <li>
    <p>If <var>path</var>[<var>index</var>]'s <a for=Event/path>root-of-closed-tree</a> is true,
    then:

    <ol>
     <li><p>Decrease <var>currentHiddenLevel</var> by 1.

     <li><p>If <var>currentHiddenLevel</var> is less than <var>maxHiddenLevel</var>, then set
     <var>maxHiddenLevel</var> to <var>currentHiddenLevel</var>.
    </ol>

   <li><p>Increase <var>index</var> by 1.
  </ol>

 <li><p>Return <var>composedPath</var>.
</ol>

<p>The <dfn attribute for=Event><code>eventPhase</code></dfn> attribute must return the value it was
initialized to, which must be one of the following:

<dl>
 <dt><dfn const for=Event>NONE</dfn> (numeric value 0)
 <dd><a>Events</a> not currently
 <a>dispatched</a> are in this phase.

 <dt><dfn const for=Event>CAPTURING_PHASE</dfn> (numeric value 1)
 <dd>When an <a>event</a> is <a>dispatched</a> to an object that <a>participates</a> in a
 <a>tree</a> it will be in this phase before it reaches its <a for=Event>target</a>.

 <dt><dfn const for=Event>AT_TARGET</dfn> (numeric value 2)
 <dd>When an <a>event</a> is <a>dispatched</a> it will be in this phase on its
 <a for=Event>target</a>.

 <dt><dfn const for=Event>BUBBLING_PHASE</dfn> (numeric value 3)
 <dd>When an <a>event</a> is <a>dispatched</a> to an object that <a>participates</a> in a
 <a>tree</a> it will be in this phase after it reaches its <a for=Event>target</a>.
</dl>

<p>Initially the attribute must be initialized to {{Event/NONE}}.

<hr>

<p>Each <a>event</a> has the following associated flags that are all initially unset:

<ul>
 <li><dfn export for=Event id=stop-propagation-flag>stop propagation flag</dfn>
 <li><dfn export for=Event id=stop-immediate-propagation-flag>stop immediate propagation flag</dfn>
 <li><dfn export for=Event id=canceled-flag>canceled flag</dfn>
 <li><dfn export for=Event id=in-passive-listener-flag>in passive listener flag</dfn>
 <li><dfn export for=Event id=composed-flag>composed flag</dfn>
 <li><dfn export for=Event id=initialized-flag>initialized flag</dfn>
 <li><dfn export for=Event id=dispatch-flag>dispatch flag</dfn>
</ul>

<p>The <dfn method for=Event><code>stopPropagation()</code></dfn> method, when invoked, must set the
<a>context object</a>'s <a>stop propagation flag</a>.</p>

<p>The <dfn attribute for=Event><code>cancelBubble</code></dfn> attribute's getter, when invoked,
must return true if the <a>context object</a>'s <a>stop propagation flag</a> is set, and false
otherwise.

<p>The {{Event/cancelBubble}} attribute's setter, when invoked, must set the <a>context object</a>'s
<a>stop propagation flag</a> if the given value is true, and do nothing otherwise.

<p>The <dfn method for=Event><code>stopImmediatePropagation()</code></dfn> method, when invoked,
must set the <a>context object</a>'s <a>stop propagation flag</a> and the <a>context object</a>'s
<a>stop immediate propagation flag</a>.</p>

<p>The <dfn attribute for=Event><code>bubbles</code></dfn> and
<dfn attribute for=Event><code>cancelable</code></dfn> attributes must return the values they were
initialized to.

<p>To <dfn>set the canceled flag</dfn>, given an <a>event</a> <var>event</var>, if
<var>event</var>'s {{Event/cancelable}} attribute value is true and <var>event</var>'s
<a>in passive listener flag</a> is unset, then set <var>event</var>'s <a>canceled flag</a>, and do
nothing otherwise.

<p>The <dfn attribute for=Event><code>returnValue</code></dfn> attribute's getter, when invoked,
must return false if <a>context object</a>'s <a>canceled flag</a> is set, and true otherwise.

<p>The {{Event/returnValue}} attribute's setter, when invoked, must <a>set the canceled flag</a>
with the <a>context object</a> if the given value is false, and do nothing otherwise.

<p>The <dfn method for=Event><code>preventDefault()</code></dfn> method, when invoked, must
<a>set the canceled flag</a> with the <a>context object</a>.

<p class="note no-backref">There are scenarios where invoking {{Event/preventDefault()}} has no
effect. User agents are encouraged to log the precise cause in a developer console, to aid
debugging.

<p>The <dfn attribute for=Event><code>defaultPrevented</code></dfn> attribute's getter, when
invoked, must return true if the <a>context object</a>'s <a>canceled flag</a> is set, and false
otherwise.</p>

<p>The <dfn attribute for=Event><code>composed</code></dfn> attribute's getter, when invoked, must
return true if the <a>context object</a>'s <a>composed flag</a> is set, and false otherwise.</p>

<hr>

<p>The <dfn attribute for=Event><code>isTrusted</code></dfn> attribute must return the value it was
initialized to. When an <a>event</a> is created the attribute must be initialized to false.

<p class="note no-backref">{{Event/isTrusted}} is a convenience that indicates whether an
<a>event</a> is <a>dispatched</a> by the user agent (as opposed to using
{{EventTarget/dispatchEvent()}}). The sole legacy exception is {{HTMLElement/click()}}, which causes
the user agent to dispatch an <a>event</a> whose {{Event/isTrusted}} attribute is initialized to
false.

<p>The <dfn attribute for=Event><code>timeStamp</code></dfn> attribute must return the value it was
initialized to.

<hr>

<p>To <dfn export for=Event id=concept-event-initialize>initialize</dfn> an <var>event</var>, with
<var>type</var>, <var>bubbles</var>, and <var>cancelable</var>, run these steps:

<ol>
 <li><p>Set <var>event</var>'s <a>initialized flag</a>.

 <li><p>Unset <var>event</var>'s <a>stop propagation flag</a>,
 <a>stop immediate propagation flag</a>, and <a>canceled flag</a>.

 <li><p>Set <var>event</var>'s {{Event/isTrusted}} attribute to false.

 <li><p>Set <var>event</var>'s <a for=Event>target</a> to null.

 <li><p>Set <var>event</var>'s {{Event/type}} attribute to <var>type</var>.

 <li><p>Set <var>event</var>'s {{Event/bubbles}} attribute to <var>bubbles</var>.

 <li><p>Set <var>event</var>'s {{Event/cancelable}} attribute to <var>cancelable</var>.
</ol>

<p>The
<dfn method for=Event><code>initEvent(<var>type</var>, <var>bubbles</var>, <var>cancelable</var>)</code></dfn>
method, when invoked, must run these steps:</p>

<ol>
 <li><p>If the <a>context object</a>'s <a>dispatch flag</a> is set, then return.

 <li><p><a>Initialize</a> the <a>context object</a> with <var>type</var>, <var>bubbles</var>, and
 <var>cancelable</var>.
</ol>

<p class="note no-backref">As <a>events</a> have constructors {{Event/initEvent()}} is redundant and
incapable of setting {{Event/composed}}. It has to be supported for legacy content.


<h3 id=interface-window-extensions>Legacy extensions to the {{Window}} interface</h3>

<pre class=idl>
partial interface Window {
  [Replaceable] readonly attribute any event; // historical
};
</pre>

<p>Each {{Window}} object has an associated <dfn for=Window>current event</dfn> (undefined or an
{{Event}} object). Unless stated otherwise it is undefined.

<p>The <dfn attribute for=Window><code>event</code></dfn> attribute's getter, when invoked, must
return the <a>context object</a>'s <a for=Window>current event</a>.

<p class=note>Web developers are strongly encouraged to instead rely on the {{Event}} object passed
to event listeners, as that will result in more portable code. This attribute is not available in
workers or worklets, and is inaccurate for events dispatched in <a>shadow trees</a>.


<h3 id=interface-customevent>Interface {{CustomEvent}}</h3>

<pre class=idl>
[Exposed=(Window,Worker)]
interface CustomEvent : Event {
  constructor(DOMString type, optional CustomEventInit eventInitDict = {});

  readonly attribute any detail;

  void initCustomEvent(DOMString type, optional boolean bubbles = false, optional boolean cancelable = false, optional any detail = null);
};

dictionary CustomEventInit : EventInit {
  any detail = null;
};
</pre>

<a>Events</a> using the
{{CustomEvent}} interface can be used to carry custom data.

<dl class=domintro>
 <dt><code><var>event</var> = new <a constructor lt="CustomEvent()">CustomEvent</a>(<var>type</var> [, <var>eventInitDict</var>])</code>
 <dd>Works analogously to the constructor for {{Event}} except
 that the <var>eventInitDict</var> argument now
 allows for setting the {{CustomEvent/detail}} attribute
 too.

 <dt><code><var>event</var> . {{CustomEvent/detail}}</code>
 <dd>Returns any custom data <var>event</var> was created with.
 Typically used for synthetic events.

 <!-- initCustomEvent is dead -->
</dl>

<p>The <dfn attribute for=CustomEvent><code>detail</code></dfn> attribute must return the value it
was initialized to.

<p>The
<dfn method for=CustomEvent><code>initCustomEvent(<var>type</var>, <var>bubbles</var>, <var>cancelable</var>, <var>detail</var>)</code></dfn>
method must, when invoked, run these steps:

<ol>
 <li><p>If the <a>context object</a>'s <a>dispatch flag</a> is set, then return.

 <li><p><a>Initialize</a> the <a>context object</a> with <var>type</var>, <var>bubbles</var>, and
 <var>cancelable</var>.

 <li><p>Set the <a>context object</a>'s {{CustomEvent/detail}} attribute to <var>detail</var>.
</ol>


<h3 id=constructing-events>Constructing events</h3>

<a lt="Other applicable specifications">Specifications</a> may define
<dfn export id=concept-event-constructor-ext>event constructing steps</dfn> for all or some
<a for=/>events</a>. The algorithm is passed an <var>event</var> as indicated in the
<a>inner event creation steps</a>.

<p class=note>This construct can be used by {{Event}} subclasses that have a more complex structure
than a simple 1:1 mapping between their initializing dictionary members and IDL attributes.

<p>When a <dfn export for=Event id=concept-event-constructor>constructor</dfn> of the {{Event}}
interface, or of an interface that inherits from the {{Event}} interface, is invoked, these steps
must be run, given the arguments <var>type</var> and <var>eventInitDict</var>:

<ol>
 <li><p>Let <var>event</var> be the result of running the <a>inner event creation steps</a> with
 this interface, null, now, and <var>eventInitDict</var>.

 <li><p>Initialize <var>event</var>'s {{Event/type}} attribute to <var>type</var>.

 <li><p>Return <var>event</var>.
</ol>

<p>To
<dfn export id=concept-event-create lt="creating an event|create an event">create an event</dfn>
using <var>eventInterface</var>, which must be either {{Event}} or an interface that inherits from
it, and optionally given a <a>Realm</a> <var>realm</var>, run these steps:</p>

<ol>
 <li><p>If <var>realm</var> is not given, then set it to null.

 <li>
  <p>Let <var>dictionary</var> be the result of <a lt="converted to an IDL value">converting</a>
  the JavaScript value undefined to the dictionary type accepted by <var>eventInterface</var>'s
  constructor. (This dictionary type will either be {{EventInit}} or a dictionary that inherits from
  it.)

  <p class="XXX">This does not work if members are required; see
  <a href="https://github.com/whatwg/dom/issues/600">whatwg/dom#600</a>.

 <li>
  <p>Let <var>event</var> be the result of running the <a>inner event creation steps</a> with
  <var>eventInterface</var>, <var>realm</var>, the time of the occurrence that the event is
  signaling, and <var>dictionary</var>.

  <p class=example id=example-timestamp-initialization>In macOS the time of the occurrence for input
  actions is available via the <code>timestamp</code> property of <code>NSEvent</code> objects.

 <li><p>Initialize <var>event</var>'s {{Event/isTrusted}} attribute to true.

 <li><p>Return <var>event</var>.
</ol>

<p class=note><a>Create an event</a> is meant to be used by other specifications which need to
separately <a lt="create an event">create</a> and <a>dispatch</a> events, instead of simply
<a lt="fire an event">firing</a> them. It ensures the event's attributes are initialized to the
correct defaults.</p>

<p>The <dfn noexport>inner event creation steps</dfn>, given an <var>interface</var>,
<var>realm</var>, <var>time</var>, and <var>dictionary</var>, are as follows:</p>

<ol>
 <li>
  <p>Let <var>event</var> be the result of creating a new object using <var>eventInterface</var>. If
  <var>realm</var> is non-null, then use that Realm; otherwise, use the default behavior defined in
  Web IDL.

  <p class="XXX">As of the time of this writing Web IDL does not yet define any default behavior;
  see <a href="https://github.com/heycam/webidl/issues/135">heycam/webidl#135</a>.

 <li><p>Set <var>event</var>'s <a>initialized flag</a>.

 <li>
  <p>Initialize <var>event</var>'s {{Event/timeStamp}} attribute to a {{DOMHighResTimeStamp}}
  representing the high resolution time from the <a>time origin</a> to <var>time</var>.

  <p class=warning>User agents should set a minimum resolution of <var>event</var>'s
  {{Event/timeStamp}} attribute to 5 microseconds following the existing <a>clock resolution</a>
  recommendation. [[!HR-TIME]]

 <li><p><a for=map>For each</a> <var>member</var> → <var>value</var> in <var>dictionary</var>, if
 <var>event</var> has an attribute whose <a spec=webidl>identifier</a> is <var>member</var>, then
 initialize that attribute to <var>value</var>.

 <li><p>Run the <a>event constructing steps</a> with <var>event</var>.

 <li><p>Return <var>event</var>.
</ol>


<h3 id=defining-event-interfaces>Defining event interfaces</h3>

In general, when defining a new interface that inherits from {{Event}} please always ask
feedback from the <a href=https://whatwg.org/>WHATWG</a> or the
<a href=https://www.w3.org/2008/webapps/>W3C WebApps WG</a> community.

The {{CustomEvent}} interface can be used as starting point.
However, do not introduce any <code>init<var ignore>*</var>Event()</code>
methods as they are redundant with constructors. Interfaces that inherit
from the {{Event}} interface that have such a method only have it
for historical reasons.


<h3 id=interface-eventtarget>Interface {{EventTarget}}</h3>

<pre class=idl>
[Exposed=(Window,Worker,AudioWorklet)]
interface EventTarget {
  constructor();

  void addEventListener(DOMString type, EventListener? callback, optional (AddEventListenerOptions or boolean) options = {});
  void removeEventListener(DOMString type, EventListener? callback, optional (EventListenerOptions or boolean) options = {});
  boolean dispatchEvent(Event event);
};

callback interface EventListener {
  void handleEvent(Event event);
};

dictionary EventListenerOptions {
  boolean capture = false;
};

dictionary AddEventListenerOptions : EventListenerOptions {
  boolean passive = false;
  boolean once = false;
};
</pre>

<p>An {{EventTarget}} object represents a target to which an <a>event</a> can be <a>dispatched</a>
when something has occurred.

<p>Each {{EventTarget}} object has an associated <dfn for=EventTarget>event listener list</dfn> (a
<a for=/>list</a> of zero or more <a>event listeners</a>). It is initially the empty list.
<!-- Intentionally not exported. -->

<p>An <dfn export id=concept-event-listener>event listener</dfn> can be used to observe a specific
<a>event</a> and consists of:

<ul class="brief">
 <li><dfn for="event listener">type</dfn> (a string)
 <li><dfn for="event listener">callback</dfn> (null or an {{EventListener}} object)
 <li><dfn for="event listener">capture</dfn> (a boolean, initially false)
 <li><dfn for="event listener">passive</dfn> (a boolean, initially false)
 <li><dfn for="event listener">once</dfn> (a boolean, initially false)
 <li><dfn for="event listener">removed</dfn> (a boolean for bookkeeping purposes, initially false)
</ul>

<p class="note no-backref">Although <a for="event listener">callback</a> is an {{EventListener}}
object, an <a>event listener</a> is a broader concept as can be seen above.

<p>Each {{EventTarget}} object also has an associated <dfn export>get the parent</dfn> algorithm,
which takes an <a>event</a> <var>event</var>, and returns an {{EventTarget}} object. Unless
specified otherwise it returns null.

<p class="note no-backref"><a for=/>Nodes</a>, <a for=/>shadow roots</a>, and <a>documents</a>
override the <a>get the parent</a> algorithm.

<p>Each {{EventTarget}} object can have an associated
<dfn export for=EventTarget>activation behavior</dfn> algorithm. The
<a for=EventTarget>activation behavior</a> algorithm is passed an <a>event</a>, as indicated in the
<a>dispatch</a> algorithm.</p>

<p class="note no-backref">This exists because user agents perform certain actions for certain
{{EventTarget}} objects, e.g., the <{area}> element, in response to synthetic {{MouseEvent}}
<a>events</a> whose {{Event/type}} attribute is <code>click</code>. Web compatibility prevented it
from being removed and it is now the enshrined way of defining an activation of something. [[!HTML]]

<p>Each {{EventTarget}} object that has <a for=EventTarget>activation behavior</a>, can additionally
have both (not either) a <dfn export for=EventTarget>legacy-pre-activation behavior</dfn> algorithm
and a <dfn export for=EventTarget>legacy-canceled-activation behavior</dfn> algorithm.

<p class="note no-backref">These algorithms only exist for checkbox and radio <{input}> elements and
are not to be used for anything else. [[!HTML]]

<dl class=domintro>
 <dt><code><var>target</var> = new <a constructor for=EventTarget lt=EventTarget()>EventTarget</a>();</code>
 <dd><p>Creates a new {{EventTarget}} object, which can be used by developers to <a>dispatch</a> and
 listen for <a>events</a>.

 <dt><code><var>target</var> . <a method for=EventTarget lt=addEventListener()>addEventListener</a>(<var>type</var>, <var>callback</var> [, <var>options</var>])</code>
 <dd>
  <p>Appends an <a>event listener</a> for <a>events</a> whose {{Event/type}} attribute value is
  <var>type</var>. The <var>callback</var> argument sets the <a for="event listener">callback</a>
  that will be invoked when the <a>event</a> is <a>dispatched</a>.

  <p>The <var>options</var> argument sets listener-specific options. For compatibility this can be a
  boolean, in which case the method behaves exactly as if the value was specified as
  <var>options</var>'s {{EventListenerOptions/capture}}.

  <p>When set to true, <var>options</var>'s {{EventListenerOptions/capture}} prevents
  <a for="event listener">callback</a> from being invoked when the <a>event</a>'s
  {{Event/eventPhase}} attribute value is {{Event/BUBBLING_PHASE}}. When false (or not present),
  <a for="event listener">callback</a> will not be invoked when <a>event</a>'s {{Event/eventPhase}}
  attribute value is {{Event/CAPTURING_PHASE}}. Either way, <a for="event listener">callback</a>
  will be invoked if <a>event</a>'s {{Event/eventPhase}} attribute value is {{Event/AT_TARGET}}.

  <p>When set to true, <var>options</var>'s {{AddEventListenerOptions/passive}} indicates that the
  <a for="event listener">callback</a> will not cancel the event by invoking
  {{Event/preventDefault()}}. This is used to enable performance optimizations described in
  [[#observing-event-listeners]].

  <p>When set to true, <var>options</var>'s {{AddEventListenerOptions/once}} indicates that the
  <a for="event listener">callback</a> will only be invoked once after which the event listener will
  be removed.

  <p>The <a>event listener</a> is appended to <var>target</var>'s
  <a for=EventTarget>event listener list</a> and is not appended if it has the same
  <a for="event listener">type</a>, <a for="event listener">callback</a>, and
  <a for="event listener">capture</a>.

 <dt><code><var>target</var> . <a method for=EventTarget lt=removeEventListener()>removeEventListener</a>(<var>type</var>, <var>callback</var> [, <var>options</var>])</code>
 <dd><p>Removes the <a>event listener</a> in <var>target</var>'s
 <a for=EventTarget>event listener list</a> with the same <var>type</var>, <var>callback</var>, and
 <var>options</var>.

 <dt><code><var>target</var> . <a method for=EventTarget lt=dispatchEvent()>dispatchEvent</a>(<var>event</var>)</code>
 <dd><p><a>Dispatches</a> a synthetic event <var>event</var> to <var>target</var> and returns true
 if either <var>event</var>'s {{Event/cancelable}} attribute value is false or its
 {{Event/preventDefault()}} method was not invoked, and false otherwise.
</dl>

<p>To <dfn export for=Event id=concept-flatten-options>flatten</dfn> <var>options</var>, run these
steps:

<ol>
 <li><p>If <var>options</var> is a boolean, then return <var>options</var>.

 <li><p>Return <var>options</var>'s <code>{{EventListenerOptions/capture}}</code>.
</ol>

<p>To <dfn export for=Event>flatten more</dfn><!-- sorry --> <var>options</var>, run these
steps:

<ol>
 <li><p>Let <var>capture</var> be the result of <a>flattening</a> <var>options</var>.

 <li><p>Let <var>once</var> and <var>passive</var> be false.

 <li><p>If <var>options</var> is a dictionary, then set <var>passive</var> to <var>options</var>'s
 <code>{{AddEventListenerOptions/passive}}</code> and <var>once</var> to <var>options</var>'s
 <code>{{AddEventListenerOptions/once}}</code>.

 <li><p>Return <var>capture</var>, <var>passive</var>, and <var>once</var>.
</ol>

<p>The <dfn constructor for=EventTarget><code>EventTarget()</code></dfn> constructor, when invoked,
must return a new {{EventTarget}}.

<p class="note">Because of the defaults stated elsewhere, the returned {{EventTarget}}'s
<a>get the parent</a> algorithm will return null, and it will have no <a>activation behavior</a>,
<a>legacy-pre-activation behavior</a>, or <a>legacy-canceled-activation behavior</a>.

<p class="note">In the future we could allow custom <a>get the parent</a> algorithms. Let us know
if this would be useful for your programs. For now, all author-created {{EventTarget}}s do not
participate in a tree structure.</p>

<p>To <dfn export>add an event listener</dfn> given an {{EventTarget}} object <var>eventTarget</var>
and an <a>event listener</a> <var>listener</var>, run these steps:

<ol>
 <li><p>If <var>eventTarget</var> is a {{ServiceWorkerGlobalScope}} object, its
 <a for="ServiceWorkerGlobalScope">service worker</a>'s
 <a for="service worker">script resource</a>'s
 <a for="script resource">has ever been evaluated flag</a> is set, and <var>listener</var>'s
 <a for="event listener">type</a> matches the {{Event/type}} attribute value of any of the
 <a>service worker events</a>, then <a>report a warning to the console</a> that this might not give
 the expected results. [[!SERVICE-WORKERS]]

 <li><p>If <var>listener</var>'s <a for="event listener">callback</a> is null, then return.

 <li><p>If <var>eventTarget</var>'s <a>event listener list</a> does not <a for=list>contain</a> an
 <a>event listener</a> whose <a for="event listener">type</a> is <var>listener</var>'s
 <a for="event listener">type</a>, <a for="event listener">callback</a> is <var>listener</var>'s
 <a for="event listener">callback</a>, and <a for="event listener">capture</a> is
 <var>listener</var>'s <a for="event listener">capture</a>, then <a for=list>append</a>
 <var>listener</var> to <var>eventTarget</var>'s <a>event listener list</a>.
</ol>

<p class=note>The <a>add an event listener</a> concept exists to ensure <a>event handlers</a> use
the same code path. [[HTML]]

<p>The
<dfn method for=EventTarget><code>addEventListener(<var>type</var>, <var>callback</var>, <var>options</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li><p>Let <var>capture</var>, <var>passive</var>, and <var>once</var> be the result of
 <a lt="flatten more">flattening more</a> <var>options</var>.

 <li><p><a>Add an event listener</a> with the <a>context object</a> and an <a>event listener</a>
 whose <a for="event listener">type</a> is <var>type</var>, <a for="event listener">callback</a> is
 <var>callback</var>, <a for="event listener">capture</a> is <var>capture</var>,
 <a for="event listener">passive</a> is <var>passive</var>, and <a for="event listener">once</a> is
 <var>once</var>.
</ol>

<p>To <dfn export>remove an event listener</dfn>, given an {{EventTarget}} object
<var>eventTarget</var> and an <a>event listener</a> <var>listener</var>, run these steps:

<ol>
 <li><p>If the <a>context object</a> is a {{ServiceWorkerGlobalScope}} object and its
 <a for="ServiceWorkerGlobalScope">service worker</a>'s
 <a for="service worker">set of event types to handle</a> contains <var>type</var>, then
 <a>report a warning to the console</a> that this might not give the expected results.
 [[!SERVICE-WORKERS]]

 <li><p>Set <var>listener</var>'s <a for="event listener">removed</a> to true and
 <a for=list>remove</a> <var>listener</var> from <var>eventTarget</var>'s
 <a for=EventTarget>event listener list</a>.
</ol>

<p class=note>HTML needs this to define event handlers. [[HTML]]

<p>To <dfn export>remove all event listeners</dfn>, given an {{EventTarget}} object
<var>eventTarget</var>, <a for=list>for each</a> <var>listener</var> of <var>eventTarget</var>'s
<a for=EventTarget>event listener list</a>, <a>remove an event listener</a> with
<var>eventTarget</var> and <var>listener</var>.

<p class=note>HTML needs this to define <code>document.open()</code>. [[HTML]]

<p>The
<dfn method for=EventTarget><code>removeEventListener(<var>type</var>, <var>callback</var>, <var>options</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li><p>Let <var>capture</var> be the result of <a>flattening</a> <var>options</var>.

 <li><p>If the <a>context object</a>'s <a for=EventTarget>event listener list</a>
 <a for=list>contains</a> an <a>event listener</a> whose <a for="event listener">type</a> is
 <var>type</var>, <a for="event listener">callback</a> is <var>callback</var>, and
 <a for="event listener">capture</a> is <var>capture</var>, then <a>remove an event listener</a>
 with the <a>context object</a> and that <a>event listener</a>.
</ol>

<p class=note>The event listener list will not contain multiple event listeners with equal
<var>type</var>, <var>callback</var>, and <var>capture</var>, as <a>add an event listener</a>
prevents that.

<p>The <dfn method for=EventTarget><code>dispatchEvent(<var>event</var>)</code></dfn> method, when
invoked, must run these steps:

<ol>
 <li><p>If <var>event</var>'s <a>dispatch flag</a> is set, or if its <a>initialized flag</a> is not
 set, then <a>throw</a> an "{{InvalidStateError!!exception}}" {{DOMException}}.

 <li><p>Initialize <var>event</var>'s {{Event/isTrusted}} attribute to false.

 <li><p>Return the result of <a>dispatching</a> <var>event</var> to the <a>context object</a>.
</ol>


<h3 id=observing-event-listeners>Observing event listeners</h3>

<p>In general, developers do not expect the presence of an <a>event listener</a> to be observable.
The impact of an <a>event listener</a> is determined by its <a for="event listener">callback</a>. That is, a developer
adding a no-op <a>event listener</a> would not expect it to have any side effects.

<p>Unfortunately, some event APIs have been designed such that implementing them efficiently
requires observing <a>event listeners</a>. This can make the presence of listeners observable in
that even empty listeners can have a dramatic performance impact on the behavior of the application.
For example, touch and wheel events which can be used to block asynchronous scrolling. In some cases
this problem can be mitigated by specifying the event to be {{Event/cancelable}} only when there is
at least one non-{{AddEventListenerOptions/passive}} listener. For example,
non-{{AddEventListenerOptions/passive}} {{TouchEvent}} listeners must block scrolling, but if all
listeners are {{AddEventListenerOptions/passive}} then scrolling can be allowed to start
<a>in parallel</a> by making the {{TouchEvent}} uncancelable (so that calls to
{{Event/preventDefault()}} are ignored). So code dispatching an event is able to observe the absence
of non-{{AddEventListenerOptions/passive}} listeners, and use that to clear the {{Event/cancelable}}
property of the event being dispatched.

<p>Ideally, any new event APIs are defined such that they do not need this property (use
<a href="https://lists.w3.org/Archives/Public/public-script-coord/">public-script-coord@w3.org</a>
for discussion).


<h3 id=dispatching-events>Dispatching events</h3>

<p>To <dfn export id=concept-event-dispatch>dispatch</dfn> an <var>event</var> to a
<var>target</var>, with an optional <var>legacy target override flag</var> and an optional
<var>legacyOutputDidListenersThrowFlag</var>, run these steps:

<ol>
 <li><p>Set <var>event</var>'s <a>dispatch flag</a>.

 <li>
  <p>Let <var>targetOverride</var> be <var>target</var>, if <var>legacy target override flag</var>
  is not given, and <var>target</var>'s <a>associated <code>Document</code></a> otherwise.
  [[!HTML]]

  <p class="note"><var>legacy target override flag</var> is only used by HTML and only when
  <var>target</var> is a {{Window}} object.

 <li><p>Let <var>activationTarget</var> be null.

 <li><p>Let <var>relatedTarget</var> be the result of <a>retargeting</a> <var>event</var>'s
 <a for=Event>relatedTarget</a> against <var>target</var>.

 <li>
  <p>If <var>target</var> is not <var>relatedTarget</var> or <var>target</var> is <var>event</var>'s
  <a for=Event>relatedTarget</a>, then:

  <ol>
   <li><p>Let <var>touchTargets</var> be a new <a for=/>list</a>.

   <li><p><a for=list>For each</a> <var>touchTarget</var> of <var>event</var>'s
   <a for=Event>touch target list</a>, <a for=list>append</a> the result of <a>retargeting</a>
   <var>touchTarget</var> against <var>target</var> to <var>touchTargets</var>.

   <li><p><a>Append to an event path</a> with <var>event</var>, <var>target</var>,
   <var>targetOverride</var>, <var>relatedTarget</var>, <var>touchTargets</var>, and false.

   <li><p>Let <var>isActivationEvent</var> be true, if <var>event</var> is a {{MouseEvent}} object
   and <var>event</var>'s {{Event/type}} attribute is "<code>click</code>", and false otherwise.

   <li><p>If <var>isActivationEvent</var> is true and <var>target</var> has
   <a for=EventTarget>activation behavior</a>, then set <var>activationTarget</var> to
   <var>target</var>.

   <li><p>Let <var>slotable</var> be <var>target</var>, if <var>target</var> is a <a>slotable</a>
   and is <a for=slotable>assigned</a>, and null otherwise.

   <li><p>Let <var>slot-in-closed-tree</var> be false.

   <li><p>Let <var>parent</var> be the result of invoking <var>target</var>'s <a>get the parent</a>
   with <var>event</var>.

   <li>
    <p>While <var>parent</var> is non-null:</p>

    <ol>
     <li>
      <p>If <var>slotable</var> is non-null:

      <ol>
       <li><p>Assert: <var>parent</var> is a <a for=/>slot</a>.

       <li><p>Set <var>slotable</var> to null.

       <li><p>If <var>parent</var>'s <a for=tree>root</a> is a <a for=/>shadow root</a> whose
       <a for=ShadowRoot>mode</a> is "<code>closed</code>", then set <var>slot-in-closed-tree</var>
       to true.
      </ol>

     <li><p>If <var>parent</var> is a <a>slotable</a> and is <a for=slotable>assigned</a>, then set
     <var>slotable</var> to <var>parent</var>.

     <li><p>Let <var>relatedTarget</var> be the result of <a>retargeting</a> <var>event</var>'s
     <a for=Event>relatedTarget</a> against <var>parent</var>.

     <li><p>Let <var>touchTargets</var> be a new <a for=/>list</a>.

     <li><p><a for=list>For each</a> <var>touchTarget</var> of <var>event</var>'s
     <a for=Event>touch target list</a>, <a for=list>append</a> the result of <a>retargeting</a>
     <var>touchTarget</var> against <var>parent</var> to <var>touchTargets</var>.

     <li>
      <p>If <var>parent</var> is a {{Window}} object, or <var>parent</var> is a <a>node</a> and
      <var>target</var>'s <a for=tree>root</a> is a <a>shadow-including inclusive ancestor</a> of
      <var>parent</var>, then:

      <ol>
       <li><p>If <var>isActivationEvent</var> is true, <var>event</var>'s {{Event/bubbles}}
       attribute is true, <var>activationTarget</var> is null, and <var>parent</var> has
       <a for=EventTarget>activation behavior</a>, then set <var>activationTarget</var> to
       <var>parent</var>.

       <li><p><a>Append to an event path</a> with <var>event</var>, <var>parent</var>, null,
       <var>relatedTarget</var>, <var>touchTargets</var>, and <var>slot-in-closed-tree</var>.
      </ol>

     <li><p>Otherwise, if <var>parent</var> is <var>relatedTarget</var>, then set <var>parent</var>
     to null.

     <li>
      <p>Otherwise, set <var>target</var> to <var>parent</var> and then:

      <ol>
       <li><p>If <var>isActivationEvent</var> is true, <var>activationTarget</var> is null, and
       <var>target</var> has <a for=EventTarget>activation behavior</a>, then set
       <var>activationTarget</var> to <var>target</var>.

       <li><p><a>Append to an event path</a> with <var>event</var>, <var>parent</var>,
       <var>target</var>, <var>relatedTarget</var>, <var>touchTargets</var>, and
       <var>slot-in-closed-tree</var>.
      </ol>

     <li><p>If <var>parent</var> is non-null, then set <var>parent</var> to the result of invoking
     <var>parent</var>'s <a>get the parent</a> with <var>event</var>.

     <li><p>Set <var>slot-in-closed-tree</var> to false.
    </ol>

   <li><p>Let <var>clearTargetsStruct</var> be the last struct in <var>event</var>'s
   <a for=Event>path</a> whose <a for=Event/path>shadow-adjusted target</a> is non-null.

   <li><p>Let <var>clearTargets</var> be true if <var>clearTargetsStruct</var>'s
   <a for=Event/path>shadow-adjusted target</a>, <var>clearTargetsStruct</var>'s
   <a for=Event/path>relatedTarget</a>, or an {{EventTarget}} object in
   <var>clearTargetsStruct</var>'s <a for=Event/path>touch target list</a> is a <a for=/>node</a>
   and its <a for=tree>root</a> is a <a for=/>shadow root</a>, and false otherwise.

   <li><p>If <var>activationTarget</var> is non-null and <var>activationTarget</var> has
   <a for=EventTarget>legacy-pre-activation behavior</a>, then run <var>activationTarget</var>'s
   <a for=EventTarget>legacy-pre-activation behavior</a>.

   <li>
    <p><a for=list>For each</a> <var>struct</var> in <var>event</var>'s <a for=Event>path</a>, in
    reverse order:

    <ol>
     <li><p>If <var>struct</var>'s <a for=Event/path>shadow-adjusted target</a> is non-null, then
     set <var>event</var>'s {{Event/eventPhase}} attribute to {{Event/AT_TARGET}}.

     <li><p>Otherwise, set <var>event</var>'s {{Event/eventPhase}} attribute to
     {{Event/CAPTURING_PHASE}}.

     <li><p><a>Invoke</a> with <var>struct</var>, <var>event</var>, "<code>capturing</code>", and
     <var>legacyOutputDidListenersThrowFlag</var> if given.
    </ol>

   <li>
    <p><a for=list>For each</a> <var>struct</var> in <var>event</var>'s <a for=Event>path</a>:

    <ol>
     <li><p>If <var>struct</var>'s <a for=Event/path>shadow-adjusted target</a> is non-null, then
     set <var>event</var>'s {{Event/eventPhase}} attribute to {{Event/AT_TARGET}}.

     <li>
      <p>Otherwise:

      <ol>
       <li><p>If <var>event</var>'s {{Event/bubbles}} attribute is false, then
       <a for=iteration>continue</a>.

       <li><p>Set <var>event</var>'s {{Event/eventPhase}} attribute to {{Event/BUBBLING_PHASE}}.
      </ol>

     <li><p><a>Invoke</a> with <var>struct</var>, <var>event</var>, "<code>bubbling</code>", and
     <var>legacyOutputDidListenersThrowFlag</var> if given.
    </ol>
  </ol>

 <li><p>Set <var>event</var>'s {{Event/eventPhase}} attribute to {{Event/NONE}}.

 <li><p>Set <var>event</var>'s {{Event/currentTarget}} attribute to null.

 <li><p>Set <var>event</var>'s <a for=Event>path</a> to the empty list.

 <li><p>Unset <var>event</var>'s <a>dispatch flag</a>, <a>stop propagation flag</a>, and
 <a>stop immediate propagation flag</a>.

 <li>
  <p>If <var>clearTargets</var>, then:

  <ol>
   <li><p>Set <var>event</var>'s <a for=Event>target</a> to null.

   <li><p>Set <var>event</var>'s <a for=Event>relatedTarget</a> to null.

   <li><p>Set <var>event</var>'s <a for=Event>touch target list</a> to the empty list.
  </ol>

 <li>
  <p>If <var>activationTarget</var> is non-null, then:

  <ol>
   <li><p>If <var>event</var>'s <a>canceled flag</a> is unset, then run
   <var>activationTarget</var>'s <a for=EventTarget>activation behavior</a> with <var>event</var>.

   <li><p>Otherwise, if <var>activationTarget</var> has
   <a for=EventTarget>legacy-canceled-activation behavior</a>, then run
   <var>activationTarget</var>'s <a for=EventTarget>legacy-canceled-activation behavior</a>.
  </ol>

 <li><p>Return false if <var>event</var>'s <a>canceled flag</a> is set, and true otherwise.
</ol>

<p>To <dfn noexport id=concept-event-path-append>append to an event path</dfn>, given an
<var>event</var>, <var>invocationTarget</var>, <var>shadowAdjustedTarget</var>,
<var>relatedTarget</var>, <var>touchTargets</var>, and a <var>slot-in-closed-tree</var>, run these
steps:</p>

<ol>
 <li><p>Let <var>invocationTargetInShadowTree</var> be false.

 <li><p>If <var>invocationTarget</var> is a <a for=/>node</a> and its <a for=tree>root</a> is a
 <a for=/>shadow root</a>, then set <var>invocationTargetInShadowTree</var> to true.

 <li><p>Let <var>root-of-closed-tree</var> be false.

 <li><p>If <var>invocationTarget</var> is a <a for=/>shadow root</a> whose <a for=ShadowRoot>mode</a>
 is "<code>closed</code>", then set <var>root-of-closed-tree</var> to true.

 <li><p><a for=list>Append</a> a new <a for=/>struct</a> to <var>event</var>'s <a for=Event>path</a>
 whose <a for=Event/path>invocation target</a> is <var>invocationTarget</var>,
 <a for=Event/path>invocation-target-in-shadow-tree</a> is <var>invocationTargetInShadowTree</var>,
 <a for=Event/path>shadow-adjusted target</a> is <var>shadowAdjustedTarget</var>,
 <a for=Event/path>relatedTarget</a> is <var>relatedTarget</var>,
 <a for=Event/path>touch target list</a> is <var>touchTargets</var>,
 <a for=Event/path>root-of-closed-tree</a> is <var>root-of-closed-tree</var>, and
 <a for=Event/path>slot-in-closed-tree</a> is <var>slot-in-closed-tree</var>.
</ol>

<p>To <dfn noexport id=concept-event-listener-invoke>invoke</dfn>, given a <var>struct</var>,
<var>event</var>, <var>phase</var>, and an optional <var>legacyOutputDidListenersThrowFlag</var>,
run these steps:

<ol>
 <li><p>Set <var>event</var>'s <a for=Event>target</a> to the
 <a for=Event/path>shadow-adjusted target</a> of the last struct in <var>event</var>'s
 <a for=Event>path</a>, that is either <var>struct</var> or preceding <var>struct</var>, whose
 <a for=Event/path>shadow-adjusted target</a> is non-null.

 <li><p>Set <var>event</var>'s <a for=Event>relatedTarget</a> to <var>struct</var>'s
 <a for=Event/path>relatedTarget</a>.

 <li><p>Set <var>event</var>'s <a for=Event>touch target list</a> to <var>struct</var>'s
 <a for=Event/path>touch target list</a>.

 <li><p>If <var>event</var>'s <a>stop propagation flag</a> is set, then return.

 <li><p>Initialize <var>event</var>'s {{Event/currentTarget}} attribute to <var>struct</var>'s
 <a for=Event/path>invocation target</a>.

 <li>
  <p>Let <var>listeners</var> be a <a for=list>clone</a> of <var>event</var>'s
  {{Event/currentTarget}} attribute value's <a for=EventTarget>event listener list</a>.

  <p class="note no-backref">This avoids <a>event listeners</a> added after this point from being
  run. Note that removal still has an effect due to the <a for="event listener">removed</a> field.

 <li><p>Let <var>found</var> be the result of running <a>inner invoke</a> with <var>event</var>,
 <var>listeners</var>, <var>phase</var>, and <var>legacyOutputDidListenersThrowFlag</var> if given.

 <li>
  <p>If <var>found</var> is false and <var>event</var>'s {{Event/isTrusted}} attribute is true,
  then:

  <ol>
   <li><p>Let <var>originalEventType</var> be <var>event</var>'s {{Event/type}} attribute value.

   <li>
    <p>If <var>event</var>'s {{Event/type}} attribute value is a match for any of the strings in the
    first column in the following table, set <var>event</var>'s {{Event/type}} attribute value to
    the string in the second column on the same row as the matching string, and return otherwise.

    <table>
     <thead>
      <tr><th>Event type<th>Legacy event type
     <tbody>
      <tr><td>"<code>animationend</code>"<td>"<code>webkitAnimationEnd</code>"
      <tr><td>"<code>animationiteration</code>"<td>"<code>webkitAnimationIteration</code>"
      <tr><td>"<code>animationstart</code>"<td>"<code>webkitAnimationStart</code>"
      <tr><td>"<code>transitionend</code>"<td>"<code>webkitTransitionEnd</code>"
    </table>

   <li><p><a>Inner invoke</a> with <var>event</var>, <var>listeners</var>, <var>phase</var>, and
   <var>legacyOutputDidListenersThrowFlag</var> if given.

   <li><p>Set <var>event</var>'s {{Event/type}} attribute value to <var>originalEventType</var>.
  </ol>
</ol>

<p>To <dfn noexport id=concept-event-listener-inner-invoke>inner invoke</dfn>, given an
<var>event</var>, <var>listeners</var>, <var>phase</var>, and an optional
<var>legacyOutputDidListenersThrowFlag</var>, run these steps:

<ol>
 <li><p>Let <var>found</var> be false.

 <li>
  <p><a for=list>For each</a> <var>listener</var> in <var>listeners</var>, whose
  <a for="event listener">removed</a> is false:

  <ol>
   <li><p>If <var>event</var>'s {{Event/type}} attribute value is not <var>listener</var>'s
   <a for="event listener">type</a>, then <a for=iteration>continue</a>.

   <li><p>Set <var>found</var> to true.

   <li><p>If <var>phase</var> is "<code>capturing</code>" and <var>listener</var>'s
   <a for="event listener">capture</a> is false, then <a for=iteration>continue</a>.

   <li><p>If <var>phase</var> is "<code>bubbling</code>" and <var>listener</var>'s
   <a for="event listener">capture</a> is true, then <a for=iteration>continue</a>.

   <li><p>If <var>listener</var>'s <a for="event listener">once</a> is true, then
   <a for=list>remove</a> <var>listener</var> from <var>event</var>'s {{Event/currentTarget}}
   attribute value's <a for=EventTarget>event listener list</a>.
   <!-- Do this before invocation to avoid reentrancy issues. No need to set removed to true since
        each listener in listeners is run once anyway. -->

   <li><p>Let <var>global</var> be <var>listener</var> <a for="event listener">callback</a>'s
   <a>associated Realm</a>'s <a for=Realm>global object</a>.

   <li><p>Let <var>currentEvent</var> be undefined.

   <li>
    <p>If <var>global</var> is a {{Window}} object, then:

    <ol>
     <li><p>Set <var>currentEvent</var> to <var>global</var>'s <a for=Window>current event</a>.

     <li><p>If <var>struct</var>'s <a for=Event/path>invocation-target-in-shadow-tree</a> is false,
     then set <var>global</var>'s <a for=Window>current event</a> to <var>event</var>.
    </ol>

   <li><p>If <var>listener</var>'s <a for="event listener">passive</a> is true, then set
   <var>event</var>'s <a>in passive listener flag</a>.

   <li>
    <p><a>Call a user object's operation</a> with <var>listener</var>'s
    <a for="event listener">callback</a>, "<code>handleEvent</code>", « <var>event</var> », and
    <var>event</var>'s {{Event/currentTarget}} attribute value. If this throws an exception, then:

    <ol>
     <li><p><a>Report the exception</a>.

     <li>
      <p>Set <var>legacyOutputDidListenersThrowFlag</var> if given.

      <p class=note>The <var>legacyOutputDidListenersThrowFlag</var> is only used by Indexed
      Database API. [[INDEXEDDB]]
    </ol>

   <li><p>Unset <var>event</var>'s <a>in passive listener flag</a>.

   <li><p>If <var>global</var> is a {{Window}} object, then set <var>global</var>'s
   <a for=Window>current event</a> to <var>currentEvent</var>.

   <li><p>If <var>event</var>'s <a>stop immediate propagation flag</a> is set, then return
   <var>found</var>.
  </ol>

 <li><p>Return <var>found</var>.
</ol>


<h3 id=firing-events>Firing events</h3>

<p>To <dfn export id=concept-event-fire>fire an event</dfn> named <var>e</var> at <var>target</var>,
optionally using an <var>eventConstructor</var>, with a description of how IDL attributes are to be
initialized, and a <var>legacy target override flag</var>, run these steps:

<ol>
 <li><p>If <var>eventConstructor</var> is not given, then let <var>eventConstructor</var> be
 {{Event}}.

 <li><p>Let <var>event</var> be the result of <a>creating an event</a> given
 <var>eventConstructor</var>, in the <a>relevant Realm</a> of <var>target</var>.

 <li><p>Initialize <var>event</var>'s {{Event/type}} attribute to <var>e</var>.

 <li>
  <p>Initialize any other IDL attributes of <var>event</var> as described in the invocation of this
  algorithm.

  <p class="note">This also allows for the {{Event/isTrusted}} attribute to be set to false.

 <li><p>Return the result of <a>dispatching</a> <var>event</var> at <var>target</var>, with
 <var>legacy target override flag</var> set if set.
</ol>

<p class="note no-backref">Fire in the context of DOM is short for
<a lt="create an event">creating</a>, initializing, and <a>dispatching</a> an <a>event</a>.
<a>Fire an event</a> makes that process easier to write down.

<div class="example no-backref" id=firing-events-example>
 <p>If the <a>event</a> needs its {{Event/bubbles}} or {{Event/cancelable}} attribute initialized,
 one could write "<a>fire an event</a> named <code>submit</code> at <var>target</var> with its
 {{Event/cancelable}} attribute initialized to true".

 <p>Or, when a custom constructor is needed, "<a>fire an event</a> named <code>click</code> at
 <var>target</var> using {{MouseEvent}} with its {{UIEvent/detail}} attribute initialized to 1".

 <p>Occasionally the return value is important:

 <ol>
  <li><p>Let <var>doAction</var> be the result of <a lt="fire an event">firing an event</a> named
  <code>like</code> at <var>target</var>.

  <li><p>If <var>doAction</var> is true, then &hellip;
 </ol>
</div>


<h3 id=action-versus-occurance>Action versus occurrence</h3>

<p>An <a>event</a> signifies an occurrence, not an action. Phrased differently, it
represents a notification from an algorithm and can be used to influence the future course
of that algorithm (e.g., through invoking {{Event/preventDefault()}}). <a>Events</a> must not be
used as actions or initiators that cause some algorithm to start running. That is not what
they are for.

<p class="note no-backref">This is called out here specifically because previous
iterations of the DOM had a concept of "default actions" associated with <a>events</a>
that gave folks all the wrong ideas. <a>Events</a> do not represent or cause actions, they
can only be used to influence an ongoing one.



<h2 id=aborting-ongoing-activities>Aborting ongoing activities</h3>

<p>Though promises do not have a built-in aborting mechanism, many APIs using them require abort
semantics. {{AbortController}} is meant to support these requirements by providing an
{{AbortController/abort()}} method that toggles the state of a corresponding {{AbortSignal}} object.
The API which wishes to support aborting can accept an {{AbortSignal}} object, and use its state to
determine how to proceed.

<p>APIs that rely upon {{AbortController}} are encouraged to respond to {{AbortController/abort()}}
by rejecting any unsettled promise with a new "{{AbortError!!exception}}" {{DOMException}}.

<div class=example id=aborting-ongoing-activities-example>
 <p>A hypothetical <code>doAmazingness({ ... })</code> method could accept an {{AbortSignal}} object
 in order to support aborting as follows:

 <pre><code class=lang-javascript>
const controller = new AbortController();
const signal = controller.signal;

startSpinner();

doAmazingness({ ..., signal })
  .then(result => ...)
  .catch(err => {
    if (err.name == 'AbortError') return;
    showUserErrorMessage();
  })
  .then(() => stopSpinner());

// &hellip;

controller.abort();</code></pre>

 <p><code>doAmazingness</code> could be implemented as follows:

 <pre><code class=lang-javascript>
function doAmazingness({signal}) {
  if (signal.aborted) {
    return Promise.reject(new DOMException('Aborted', 'AbortError'));
  }

  return new Promise((resolve, reject) => {
    // Begin doing amazingness, and call resolve(result) when done.
    // But also, watch for signals:
    signal.addEventListener('abort', () => {
      // Stop doing amazingness, and:
      reject(new DOMException('Aborted', 'AbortError'));
    });
  });
}
</code></pre>

 <p>APIs that require more granular control could extend both {{AbortController}} and
 {{AbortSignal}} objects according to their needs.
</div>


<h3 id=interface-abortcontroller>Interface {{AbortController}}</h3>

<pre class="idl">
[Exposed=(Window,Worker)]
interface AbortController {
  constructor();

  [SameObject] readonly attribute AbortSignal signal;

  void abort();
};
</pre>

<dl class=domintro>
 <dt><code><var>controller</var> = new <a constructor lt=AbortController()>AbortController</a>()</code>
 <dd>Returns a new <var>controller</var> whose {{AbortController/signal}} is set to a newly
 created {{AbortSignal}} object.

 <dt><code><var>controller</var> . <a attribute for=AbortController>signal</a></code>
 <dd>Returns the {{AbortSignal}} object associated with this object.

 <dt><code><var>controller</var> . <a method for=AbortController lt=abort()>abort</a>()</code>
 <dd>Invoking this method will set this object's {{AbortSignal}}'s [=AbortSignal/aborted flag=] and
 signal to any observers that the associated activity is to be aborted.
</dl>

<p>An {{AbortController}} object has an associated <dfn for=AbortController>signal</dfn> (an
{{AbortSignal}} object).

<p>The <dfn constructor for=AbortController><code>AbortController()</code></dfn> constructor, when
invoked, must run these steps:

<ol>
 <li><p>Let <var>signal</var> be a new {{AbortSignal}} object.

 <li><p>Let <var>controller</var> be a new {{AbortController}} object whose
 <a for=AbortController>signal</a> is <var>signal</var>.

 <li><p>Return <var>controller</var>.
</ol>

<p>The <dfn attribute for=AbortController><code>signal</code></dfn> attribute's getter, when
invoked, must return the <a>context object</a>'s <a for=AbortController>signal</a>.

<p>The <dfn method for=AbortController><code>abort()</code></dfn> method, when invoked, must
<a for=AbortSignal>signal abort</a> on the <a>context object</a>'s
<a for=AbortController>signal</a>.


<h3 id=interface-AbortSignal>Interface {{AbortSignal}}</h3>

<pre class="idl">
[Exposed=(Window,Worker)]
interface AbortSignal : EventTarget {
  readonly attribute boolean aborted;

  attribute EventHandler onabort;
};</pre>

<dl class=domintro>
 <dt><code><var>signal</var> . <a attribute for=AbortSignal>aborted</a></code>
 <dd>Returns true if this {{AbortSignal}}'s {{AbortController}} has signaled to abort, and false
 otherwise.
</dl>

<p>An {{AbortSignal}} object has an associated <dfn export for=AbortSignal>aborted flag</dfn>. It is
unset unless specified otherwise.

<p>An {{AbortSignal}} object has associated <dfn for=AbortSignal>abort algorithms</dfn>, which is a
<a for=/>set</a> of algorithms which are to be executed when its [=AbortSignal/aborted flag=] is
set. Unless specified otherwise, its value is the empty set.

<p>To <dfn export for=AbortSignal>add</dfn> an algorithm <var>algorithm</var> to an {{AbortSignal}}
object <var>signal</var>, run these steps:

<ol>
 <li><p>If <var>signal</var>'s <a for=AbortSignal>aborted flag</a> is set, then return.

 <li><p><a for=set>Append</a> <var>algorithm</var> to <var>signal</var>'s
 <a for=AbortSignal>abort algorithms</a>.
</ol>

<p>To <dfn export for=AbortSignal>remove</dfn> an algorithm <var>algorithm</var> from an
{{AbortSignal}} <var>signal</var>, <a for=set>remove</a> <var>algorithm</var> from
<var>signal</var>'s <a for=AbortSignal>abort algorithms</a>.

<p class="note no-backref">The [=AbortSignal/abort algorithms=] enable APIs with complex
requirements to react in a reasonable way to {{AbortController/abort()}}. For example, a given API's
[=AbortSignal/aborted flag=] might need to be propagated to a cross-thread environment, such as a
service worker.

<p>The <dfn attribute for=AbortSignal>aborted</dfn> attribute's getter, when invoked, must return
true if the <a>context object</a>'s [=AbortSignal/aborted flag=] is set, and false otherwise.

<p>The <dfn attribute for=AbortSignal><code>onabort</code></dfn> attribute is an
<a>event handler IDL attribute</a> for the <dfn export for=AbortSignal><code>onabort</code></dfn>
<a>event handler</a>, whose <a>event handler event type</a> is
<dfn event for=AbortSignal><code>abort</code></dfn>.

<p class=note>Changes to an {{AbortSignal}} object represent the wishes of the corresponding
{{AbortController}} object, but an API observing the {{AbortSignal}} object can chose to ignore
them. For instance, if the operation has already completed.

<p>To <dfn export for=AbortSignal>signal abort</dfn>, given a {{AbortSignal}} object
<var>signal</var>, run these steps:

<ol>
 <li><p>If <var>signal</var>'s [=AbortSignal/aborted flag=] is set, then return.

 <li><p>Set <var>signal</var>'s [=AbortSignal/aborted flag=].

 <li><p><a for=set>For each</a> <var>algorithm</var> in <var>signal</var>'s
 [=AbortSignal/abort algorithms=]: run <var>algorithm</var>.

 <li><p><a for=set>Empty</a> <var>signal</var>'s <a for=AbortSignal>abort algorithms</a>.

 <li><p>[=Fire an event=] named {{AbortSignal/abort}} at <var>signal</var>.
</ol>

<p>A <var>followingSignal</var> (an {{AbortSignal}}) is made to
<dfn export for=AbortSignal>follow</dfn> a <var>parentSignal</var> (an {{AbortSignal}}) by running
these steps:

<ol>
 <li><p>If <var>followingSignal</var>'s [=AbortSignal/aborted flag=] is set, then return.

 <li><p>If <var>parentSignal</var>'s [=AbortSignal/aborted flag=] is set, then
 <a for=AbortSignal>signal abort</a> on <var>followingSignal</var>.

 <li>
  <p>Otherwise, <a for=AbortSignal lt=add>add the following abort steps</a> to
  <var>parentSignal</var>:

  <ol>
   <li><p><a for=AbortSignal>Signal abort</a> on <var>followingSignal</var>.
  </ol>
</ol>


<h3 id=abortcontroller-api-integration>Using {{AbortController}} and {{AbortSignal}} objects in
APIs</h3>

<p>Any web platform API using promises to represent operations that can be aborted must adhere to
the following:

<ul class=brief>
 <li>Accept {{AbortSignal}} objects through a <code>signal</code> dictionary member.
 <li>Convey that the operation got aborted by rejecting the promise with an
 "{{AbortError!!exception}}" {{DOMException}}.
 <li>Reject immediately if the {{AbortSignal}}'s [=AbortSignal/aborted flag=] is already set,
 otherwise:
 <li>Use the [=AbortSignal/abort algorithms=] mechanism to observe changes to the {{AbortSignal}}
 object and do so in a manner that does not lead to clashes with other observers.
</ul>

<div class=example id=aborting-ongoing-activities-spec-example>
 <p>The steps for a promise-returning method <code>doAmazingness(options)</code> could be as
 follows:

 <ol>
  <li><p>Let |p| be [=a new promise=].

  <li>
   <p>If |options|' <code>signal</code> member is present, then:

   <ol>
    <li><p>If |options|' <code>signal</code>'s [=AbortSignal/aborted flag=] is set, then [=reject=]
    |p| with an "{{AbortError!!exception}}" {{DOMException}} and return |p|.

    <li>
     <p>[=AbortSignal/Add|Add the following abort steps=] to |options|' <code>signal</code>:

     <ol>
      <li><p>Stop doing amazing things.

      <li><p>[=Reject=] |p| with an "{{AbortError!!exception}}" {{DOMException}}.
     </ol>
   </ol>

  <li>
   <p>Run these steps [=in parallel=]:

   <ol>
    <li><p>Let |amazingResult| be the result of doing some amazing things.

    <li><p>[=/Resolve=] |p| with |amazingResult|.
   </ol>

  <li><p>Return |p|.
 </ol>
</div>

<p>APIs not using promises should still adhere to the above as much as possible.



<h2 id=nodes>Nodes</h2>

<h3 id=introduction-to-the-dom>Introduction to "The DOM"</h3>

In its original sense, "The DOM" is an API for
accessing and manipulating documents (in particular, HTML and XML
documents). In this specification, the term "document" is used for any
markup-based resource, ranging from short static documents to long essays or
reports with rich multimedia, as well as to fully-fledged interactive
applications.

<p>Each such document is represented as a <a>node tree</a>. Some of the <a for=/>nodes</a> in a
<a>tree</a> can have <a>children</a>, while others are always leaves.

To illustrate, consider this HTML document:

<pre class='lang-markup'>
&lt;!DOCTYPE html>
&lt;html class=e>
 &lt;head>&lt;title>Aliens?&lt;/title>&lt;/head>
 &lt;body>Why yes.&lt;/body>
&lt;/html>
</pre>

It is represented as follows:

<ul class="domTree">
 <li>
  <a>Document</a>
  <ul>
   <li class="t10"><a>Doctype</a>: <code>html</code>
   <li class="t1">{{Element}}: <code>html</code> <span class="t2"><code class="attribute name">class</code>="<code class="attribute value">e</code>"</span>
    <ul>
     <li class="t1">
      {{Element}}: <code>head</code>
      <ul>
       <li class="t1">
        {{Element}}: <code>title</code>
        <ul>
         <li class="t3">{{Text}}: <span>Aliens?</span>
        </ul>

      </ul>

     <li class="t3">{{Text}}: <span>⏎␣</span>
     <li class="t1">
      {{Element}}: <code>body</code>
      <ul>
       <li class="t3">{{Text}}: <span>Why yes.⏎</span>
      </ul>

    </ul>

  </ul>

</ul>

<!--
https://software.hixie.ch/utilities/js/live-dom-viewer/?%3C!DOCTYPE%20html%3E%0D%0A%3Chtml%20class%3De%3E%0D%0A%20%3Chead%3E%3Ctitle%3EAliens%3F%3C%2Ftitle%3E%3C%2Fhead%3E%0D%0A%20%3Cbody%3EWhy%20yes.%3C%2Fbody%3E%0D%0A%3C%2Fhtml%3E
-->

<p>Note that, due to the magic that is <a lt="html parser">HTML parsing</a>, not all
<a>ASCII whitespace</a> were turned into {{Text}} <a for=/>nodes</a>, but the general concept is
clear. Markup goes in, a <a>tree</a> of <a for=/>nodes</a> comes out.
<!-- You /can/ explain that! harharhar -->

<p class="note no-backref">The most excellent
<a href="https://software.hixie.ch/utilities/js/live-dom-viewer/">Live DOM Viewer</a>
can be used to explore this matter in more detail.


<h3 id=node-trees>Node tree</h3>

<p>{{Document}}, {{DocumentType}}, {{DocumentFragment}}, {{Element}}, {{Text}},
{{ProcessingInstruction}}, and {{Comment}} objects (simply called
<dfn export id=concept-node>nodes</dfn>) <a>participate</a> in a <a>tree</a>, simply named the
<dfn export id=concept-node-tree>node tree</dfn>.

<p>A <a>node tree</a> is constrained as follows, expressed as a relationship between the type of
<a>node</a> and its allowed <a>children</a>:

<dl>
 <dt>{{Document}}
 <dd>
  <p>In <a>tree order</a>:
  <ol>
   <li><p>Zero or more nodes each of which is {{ProcessingInstruction}} or {{Comment}}.
   <li><p>Optionally one {{DocumentType}} node.
   <li><p>Zero or more nodes each of which is {{ProcessingInstruction}} or {{Comment}}.
   <li><p>Optionally one {{Element}} node.
   <li><p>Zero or more nodes each of which is {{ProcessingInstruction}} or {{Comment}}.
  </ol>
 <dt>{{DocumentFragment}}
 <dt>{{Element}}
 <dd><p>Zero or more nodes each of which is {{Element}}, {{Text}}, {{ProcessingInstruction}}, or
 {{Comment}}.
 <dt>{{DocumentType}}
 <dt>{{Text}}
 <dt>{{ProcessingInstruction}}
 <dt>{{Comment}}
 <dd><p>None.
</dl>

<p>To determine the <dfn export id=concept-node-length for=Node>length</dfn> of a <a>node</a>
<var>node</var>, switch on <var>node</var>:

<dl class=switch>
 <dt>{{DocumentType}}
 <dd><p>Zero.

 <dt>{{Text}}
 <dt>{{ProcessingInstruction}}
 <dt>{{Comment}}
 <dd><p>Its <a for=CharacterData>data</a>'s <a for="JavaScript string">length</a>.

 <dt>Any other node
 <dd><p>Its number of <a>children</a>.
</dl>

<p>A <a>node</a> is considered <dfn export id=concept-node-empty for=Node>empty</dfn> if its
<a>length</a> is zero.


<h4 id=document-trees>Document tree</h4>

<p>A <dfn export id=concept-document-tree>document tree</dfn> is a <a>node tree</a> whose
<a for=tree>root</a> is a <a>document</a>.

<p>The <dfn export>document element</dfn> of a <a>document</a> is the <a for="/">element</a> whose
<a for=tree>parent</a> is that <a>document</a>, if it exists, and null otherwise.

<p class="note no-backref">Per the <a>node tree</a> constraints, there can be only one such
<a for="/">element</a>.

<p>An <a for=/>element</a> is <dfn export>in a document tree</dfn> if its <a for=tree>root</a> is a
<a>document</a>.

<p>An <a for=/>element</a> is <dfn export>in a document</dfn> if it is <a>in a document tree</a>.
<span class="note">The term <a>in a document</a> is no longer supposed to be used. It indicates that
the standard using it has not been updated to account for <a>shadow trees</a>.</span>


<h4 id=shadow-trees>Shadow tree</h4>

<p>A <dfn export id=concept-shadow-tree>shadow tree</dfn> is a <a>node tree</a> whose
<a for=tree>root</a> is a <a for=/>shadow root</a>.

<p>A <a for=/>shadow root</a> is always attached to another <a>node tree</a> through its
<a for=DocumentFragment>host</a>. A <a>shadow tree</a> is therefore never alone. The
<a>node tree</a> of a <a for=/>shadow root</a>'s <a for=DocumentFragment>host</a> is sometimes
referred to as the <dfn export id=concept-light-tree>light tree</dfn>.</p>

<p class="note">A <a>shadow tree</a>'s corresponding <a>light tree</a> can be a <a>shadow tree</a>
itself.</p>

<p id=in-a-shadow-including-document>An <a for=/>element</a> is <dfn export>connected</dfn> if its
<a>shadow-including root</a> is a <a>document</a>.

<h5 id=shadow-tree-slots>Slots</h5>

<p>A <a>shadow tree</a> contains zero or more <a for=/>elements</a> that are
<dfn export id=concept-slot lt=slot>slots</dfn>.</p>

<p class="note">A <a>slot</a> can only be created through HTML's <{slot}> element.</p>

<p>A <a>slot</a> has an associated <dfn export for=slot>name</dfn> (a string). Unless stated
otherwise it is the empty string.</p>

<p>Use these <a>attribute change steps</a> to update a <a>slot</a>'s <a for=slot>name</a>:

<ol>
 <li>
  <p>If <var>element</var> is a <a>slot</a>, <var>localName</var> is <code>name</code>, and
  <var>namespace</var> is null, then:

  <ol>
   <li><p>If <var>value</var> is <var>oldValue</var>, then return.

   <li><p>If <var>value</var> is null and <var>oldValue</var> is the empty string, then return.

   <li><p>If <var>value</var> is the empty string and <var>oldValue</var> is null, then return.

   <li><p>If <var>value</var> is null or the empty string, then set <var>element</var>'s
   <a for=slot>name</a> to the empty string.

   <li><p>Otherwise, set <var>element</var>'s <a for=slot>name</a> to <var>value</var>.

   <li><p>Run <a>assign slotables for a tree</a> with <var>element</var>'s <a for=tree>root</a>.
  </ol>
</ol>

<p class="note">The first <a>slot</a> in a <a>shadow tree</a>, in <a>tree order</a>, whose
<a for=slot>name</a> is the empty string, is sometimes known as the "default slot".</p>

<p>A <a>slot</a> has an associated <dfn export for=slot>assigned nodes</dfn> (a list of
<a>slotables</a>). Unless stated otherwise it is empty.</p>

<h5 id=light-tree-slotables>Slotables</h5>

<p>{{Element}} and {{Text}} <a for=/>nodes</a> are
<dfn export id=concept-slotable lt=slotable>slotables</dfn>.</p>

<p class="note">A <a>slot</a> can be a <a>slotable</a>.

<p>A <a>slotable</a> has an associated <dfn export for=slotable>name</dfn> (a string). Unless stated
otherwise it is the empty string.</p>

<p>Use these <a>attribute change steps</a> to update a <a>slotable</a>'s <a for=slotable>name</a>:

<ol>
 <li>
  <p>If <var>localName</var> is <code>slot</code> and <var>namespace</var> is null, then:

  <ol>
   <li><p>If <var>value</var> is <var>oldValue</var>, then return.

   <li><p>If <var>value</var> is null and <var>oldValue</var> is the empty string, then return.

   <li><p>If <var>value</var> is the empty string and <var>oldValue</var> is null, then return.

   <li><p>If <var>value</var> is null or the empty string, then set <var>element</var>'s
   <a for=slotable>name</a> to the empty string.

   <li><p>Otherwise, set <var>element</var>'s <a for=slotable>name</a> to <var>value</var>.

   <li><p>If <var>element</var> is <a for=slotable>assigned</a>, then run <a>assign slotables</a>
   for <var>element</var>'s <a for=slotable>assigned slot</a>.

   <li><p>Run <a>assign a slot</a> for <var>element</var>.
  </ol>
</ol>

<p>A <a>slotable</a> has an associated <dfn export for=slotable>assigned slot</dfn> (null or a
<a>slot</a>). Unless stated otherwise it is null. A <a>slotable</a> is
<dfn export for=slotable>assigned</dfn> if its <a>assigned slot</a> is non-null.</p>

<h5 id=finding-slots-and-slotables>Finding slots and slotables</h5>

<p>To <dfn export lt="find a slot|finding a slot">find a slot</dfn> for a given <a>slotable</a>
<var>slotable</var> and an optional <i>open flag</i> (unset unless stated otherwise), run these
steps:</p>

<ol>
 <li><p>If <var>slotable</var>'s <a for=tree>parent</a> is null, then return null.</p></li>

 <li><p>Let <var>shadow</var> be <var>slotable</var>'s <a for=tree>parent</a>'s
 <a for=Element>shadow root</a>.</p></li>

 <li><p>If <var>shadow</var> is null, then return null.</p></li>

 <li><p>If the <i>open flag</i> is set and <var>shadow</var>'s <a for=ShadowRoot>mode</a> is
 <em>not</em> "<code>open</code>", then return null.</p></li>

 <li><p>Return the first <a>slot</a> in <a>tree order</a> in <var>shadow</var>'s
 <a for=tree>descendants</a> whose <a for=slot>name</a> is <var>slotable</var>'s
 <a for=slotable>name</a>, if any, and null otherwise.</p></li>
</ol>

<p>To <dfn export lt="find slotables|finding slotables">find slotables</dfn> for a given <a>slot</a>
<var>slot</var>, run these steps:</p>

<ol>
 <li><p>Let <var>result</var> be an empty list.</p></li>

 <li><p>If <var>slot</var>'s <a for=tree>root</a> is not a <a for=/>shadow root</a>, then return
 <var>result</var>.</p></li>

 <li><p>Let <var>host</var> be <var>slot</var>'s <a for=tree>root</a>'s
 <a for=DocumentFragment>host</a>.</p></li>

 <li>
  <p>For each <a>slotable</a> <a for=tree>child</a> of <var>host</var>, <var>slotable</var>, in
  <a>tree order</a>:</p>

  <ol>
   <li><p>Let <var>foundSlot</var> be the result of <a>finding a slot</a> given
   <var>slotable</var>.</p></li>

   <li><p>If <var>foundSlot</var> is <var>slot</var>, then append <var>slotable</var> to
   <var>result</var>.</p></li>
  </ol>
 </li>

 <li><p>Return <var>result</var>.</p></li>
</ol>

<p>To
<dfn export lt="find flattened slotables|finding flattened slotables">find flattened slotables</dfn>
for a given <a>slot</a> <var>slot</var>, run these steps:</p>

<ol>
 <li><p>Let <var>result</var> be an empty list.</p></li>

 <li><p>If <var>slot</var>'s <a for=tree>root</a> is not a <a for=/>shadow root</a>, then return
 <var>result</var>.</p></li>

 <li><p>Let <var>slotables</var> be the result of <a>finding slotables</a> given
 <var>slot</var>.</p></li>

 <li><p>If <var>slotables</var> is the empty list, then append each <a>slotable</a>
 <a for=tree>child</a> of <var>slot</var>, in <a>tree order</a>, to <var>slotables</var>.</p></li>

 <li>
  <p>For each <var>node</var> in <var>slotables</var>:

  <ol>
   <li>
    <p>If <var>node</var> is a <a>slot</a> whose <a for=tree>root</a> is a <a for=/>shadow root</a>,
    then:

    <ol>
     <li><p>Let <var>temporaryResult</var> be the result of <a>finding flattened slotables</a> given
     <var>node</var>.</p></li>

     <li><p>Append each <a>slotable</a> in <var>temporaryResult</var>, in order, to
     <var>result</var>.</p></li>
    </ol>

   <li><p>Otherwise, append <var>node</var> to <var>result</var>.</p></li>
  </ol>
 </li>

 <li><p>Return <var>result</var>.</p></li>
</ol>

<h5 id=assigning-slotables-and-slots>Assigning slotables and slots</h5>

<p>To <dfn noexport>assign slotables</dfn> for a <a>slot</a> <var>slot</var>, run these steps:

<ol>
 <li><p>Let <var>slotables</var> be the result of <a>finding slotables</a> for <var>slot</var>.

 <li><p>If <var>slotables</var> and <var>slot</var>'s <a for=slot>assigned nodes</a> are not
 identical, then run <a>signal a slot change</a> for <var>slot</var>.

 <li><p>Set <var>slot</var>'s <a for=slot>assigned nodes</a> to <var>slotables</var>.

 <li><p>For each <var>slotable</var> in <var>slotables</var>, set <var>slotable</var>'s
 <a>assigned slot</a> to <var>slot</var>.
</ol>

<p>To <dfn noexport>assign slotables for a tree</dfn>, given a <a for=/>node</a>
<var>root</var>, run <a>assign slotables</a> for each <a>slot</a> <var>slot</var> in
<var>root</var>'s <a for=tree>inclusive descendants</a>, in <a>tree order</a>.

<p>To <dfn noexport>assign a slot</dfn>, given a <a>slotable</a> <var>slotable</var>, run these
steps:

<ol>
 <li><p>Let <var>slot</var> be the result of <a>finding a slot</a> with <var>slotable</var>.

 <li><p>If <var>slot</var> is non-null, then run <a>assign slotables</a> for <var>slot</var>.
</ol>

<h5 id=signaling-slot-change>Signaling slot change</h5>

<p>Each <a>similar-origin window agent</a> has <dfn noexport id=signal-slot-list>signal slots</dfn>
(a <a for=/>set</a> of <a>slots</a>), which is initially empty. [[!HTML]]

<p>To <dfn noexport>signal a slot change</dfn>, for a <a>slot</a> <var>slot</var>, run these steps:

<ol>
 <li><p><a for=set>Append</a> <var>slot</var> to <var>slot</var>'s <a>relevant agent</a>'s
 <a>signal slots</a>.

 <li><p><a>Queue a mutation observer microtask</a>.
</ol>


<h4 id=mutation-algorithms>Mutation algorithms</h4>

<p>To
<dfn export for=Node id=concept-node-ensure-pre-insertion-validity>ensure pre-insertion validity</dfn>
of a <var>node</var> into a <var>parent</var> before a <var>child</var>, run these steps:

<ol>
 <li><p>If <var>parent</var> is not a {{Document}}, {{DocumentFragment}}, or {{Element}}
 <a>node</a>, then <a>throw</a> a "{{HierarchyRequestError!!exception}}" {{DOMException}}.

 <li><p>If <var>node</var> is a <a>host-including inclusive ancestor</a> of <var>parent</var>, then
 <a>throw</a> a "{{HierarchyRequestError!!exception}}" {{DOMException}}.

 <li><p>If <var>child</var> is non-null and its <a for=tree>parent</a> is not <var>parent</var>,
 then <a>throw</a> a "{{NotFoundError!!exception}}" {{DOMException}}.

 <li><p>If <var>node</var> is not a {{DocumentFragment}}, {{DocumentType}}, {{Element}}, {{Text}},
 {{ProcessingInstruction}}, or {{Comment}} <a>node</a>, then <a>throw</a> a
 "{{HierarchyRequestError!!exception}}" {{DOMException}}.

 <li><p>If either <var>node</var> is a {{Text}} <a>node</a> and <var>parent</var> is a
 <a>document</a>, or <var>node</var> is a <a>doctype</a> and <var>parent</var> is not a
 <a>document</a>, then <a>throw</a> a "{{HierarchyRequestError!!exception}}" {{DOMException}}.

 <li>
  <p>If <var>parent</var> is a <a>document</a>, and any of the statements below, switched on
  <var>node</var>, are true, then <a>throw</a> a
  "{{HierarchyRequestError!!exception}}" {{DOMException}}.

  <dl class=switch>
   <dt>{{DocumentFragment}} <a>node</a>
   <dd>
    <p>If <var>node</var> has more than one <a for="/">element</a> <a for=tree>child</a> or has a
    {{Text}} <a>node</a> <a for=tree>child</a>.

    <p>Otherwise, if <var>node</var> has one <a for="/">element</a> <a for=tree>child</a> and either
    <var>parent</var> has an <a for="/">element</a> <a for=tree>child</a>, <var>child</var> is a
    <a>doctype</a>, or <var>child</var> is non-null and a <a>doctype</a> is <a>following</a>
    <var>child</var>.
    <!--"inclusively following"-->

   <dt><a for="/">element</a>
   <dd><p><var>parent</var> has an <a for="/">element</a> <a for=tree>child</a>, <var>child</var> is
   a <a>doctype</a>, or <var>child</var> is non-null and a <a>doctype</a> is <a>following</a>
   <var>child</var>.
   <!--"inclusively following"-->

   <dt><a>doctype</a>
   <dd><p><var>parent</var> has a <a>doctype</a> <a for=tree>child</a>, <var>child</var> is non-null
   and an <a for="/">element</a> is <a>preceding</a> <var>child</var>, or <var>child</var> is null
   and <var>parent</var> has an <a for="/">element</a> <a for=tree>child</a>.
  </dl>
</ol>

<p>To <dfn export id=concept-node-pre-insert>pre-insert</dfn> a <var>node</var> into a
<var>parent</var> before a <var>child</var>, run these steps:

<ol>
 <li><p><a>Ensure pre-insertion validity</a> of <var>node</var> into <var>parent</var> before
 <var>child</var>.

 <li><p>Let <var>referenceChild</var> be <var>child</var>.

 <li><p>If <var>referenceChild</var> is <var>node</var>, then set <var>referenceChild</var> to
 <var>node</var>'s <a for=tree>next sibling</a>.

 <li><p><a for=/>Insert</a> <var>node</var> into <var>parent</var> before <var>referenceChild</var>.

 <li><p>Return <var>node</var>.
 <!-- Technically this is post-insert. -->
</ol>

<p><a lt="Other applicable specifications">Specifications</a> may define
<dfn export id=concept-node-insert-ext>insertion steps</dfn> for all or some <a for=/>nodes</a>. The
algorithm is passed <var ignore>insertedNode</var>, as indicated in the <a for=/>insert</a>
algorithm below.
<!-- See https://github.com/whatwg/dom/issues/34#issuecomment-125571750 for why we might need to
     adjust this further based on the requirements of the script element. There might be other ways
     to define that though as Olli suggests, so leaving that out for now. -->

<p><a lt="other applicable specifications">Specifications</a> may define
<dfn export id=concept-node-children-changed-ext>children changed steps</dfn> for all or some
<a for=/>nodes</a>. The algorithm is passed no argument and is called from <a for=/>insert</a>,
<a for=/>remove</a>, and <a for=/>replace data</a>.

<p>To <dfn export id=concept-node-insert>insert</dfn> a <var>node</var> into a <var>parent</var>
before a <var>child</var>, with an optional <i>suppress observers flag</i>, run these steps:

<ol>
 <li><p>Let <var>nodes</var> be <var>node</var>'s <a>children</a>, if <var>node</var> is a
 {{DocumentFragment}} <a>node</a>; otherwise « <var>node</var> ».

 <li><p>Let <var>count</var> be <var>nodes</var>'s <a for=set>size</a>.

 <li><p>If <var>count</var> is 0, then return.

 <li>
  <p>If <var>node</var> is a {{DocumentFragment}} <a>node</a>, then:

  <ol>
   <li><p><a for=/>Remove</a> its <a>children</a> with the <i>suppress observers flag</i> set.

   <li>
    <p><a>queue a tree mutation record</a> for <var>node</var> with « », <var>nodes</var>, null, and
    null.

    <p class="note no-backref">This step intentionally does not pay attention to the
    <i>suppress observers flag</i>.
  </ol>

 <li>
  <p>If <var>child</var> is non-null, then:

  <ol>
   <li><p>For each <a>live range</a> whose <a for=range>start node</a> is <var>parent</var> and
   <a for=range>start offset</a> is greater than <var>child</var>'s <a for=tree>index</a>, increase
   its <a for=range>start offset</a> by <var>count</var>.

   <li><p>For each <a>live range</a> whose <a for=range>end node</a> is <var>parent</var> and
   <a for=range>end offset</a> is greater than <var>child</var>'s <a for=tree>index</a>, increase
   its <a for=range>end offset</a> by <var>count</var>.
  </ol>

 <li><p>Let <var>previousSibling</var> be <var>child</var>'s <a>previous sibling</a> or
 <var>parent</var>'s <a>last child</a> if <var>child</var> is null.

 <li>
  <p>For each <var>node</var> in <var>nodes</var>, in <a>tree order</a>:

  <ol>
   <li><p><a>Adopt</a> <var>node</var> into <var>parent</var>'s <a for=Node>node document</a>.

   <li><p>If <var>child</var> is null, then <a for=set>append</a> <var>node</var> to
   <var>parent</var>'s <a for=tree>children</a>.

   <li><p>Otherwise, <a for=set>insert</a> <var>node</var> into <var>parent</var>'s
   <a for=tree>children</a> before <var>child</var>'s <a for=tree>index</a>.

   <li><p>If <var>parent</var> is a <a for=Element>shadow host</a> and <var>node</var> is a
   <a>slotable</a>, then <a>assign a slot</a> for <var>node</var>.

   <li><p>If <var>parent</var>'s <a for=tree>root</a> is a <a for=/>shadow root</a>, and
   <var>parent</var> is a <a>slot</a> whose <a for=slot>assigned nodes</a> is the empty list,
   then run <a>signal a slot change</a> for <var>parent</var>.

   <li><p>Run <a>assign slotables for a tree</a> with <var>node</var>'s <a for=tree>root</a>.

   <li>
    <p>For each <a>shadow-including inclusive descendant</a> <var>inclusiveDescendant</var> of
    <var>node</var>, in <a>shadow-including tree order</a>:

    <ol>
     <li><p>Run the <a>insertion steps</a> with <var>inclusiveDescendant</var>.

     <li>
      <p>If <var>inclusiveDescendant</var> is <a>connected</a>, then:

      <ol>
       <li><p>If <var>inclusiveDescendant</var> is <a for=Element>custom</a>, then
       <a>enqueue a custom element callback reaction</a> with <var>inclusiveDescendant</var>,
       callback name "<code>connectedCallback</code>", and an empty argument list.

       <li>
        <p>Otherwise, <a lt="try to upgrade an element">try to upgrade</a>
        <var>inclusiveDescendant</var>.

        <p class=note>If this successfully upgrades <var>inclusiveDescendant</var>, its
        <code>connectedCallback</code> will be enqueued automatically during the
        <a>upgrade an element</a> algorithm.
      </ol>
     </li>
    </ol>
   </li>
  </ol>

 <li><p>If <i>suppress observers flag</i> is unset, then <a>queue a tree mutation record</a> for
 <var>parent</var> with <var>nodes</var>, « », <var>previousSibling</var>, and <var>child</var>.

 <li><p>Run the <a>children changed steps</a> for <var>parent</var>.
</ol>


<p>To <dfn export id=concept-node-append>append</dfn> a <var>node</var> to a <var>parent</var>,
<a>pre-insert</a> <var>node</var> into <var>parent</var> before null.


<p>To <dfn export id=concept-node-replace>replace</dfn> a <var>child</var> with <var>node</var>
within a <var>parent</var>, run these steps:

<!-- Step 1-5 could be shared with concept-node-pre-insert, although step 3
     in pre-insert is a superset (which is fine). Step 6.1.1 could also be
     shared. -->

<ol>
 <li><p>If <var>parent</var> is not a {{Document}}, {{DocumentFragment}}, or {{Element}}
 <a>node</a>, then <a>throw</a> a "{{HierarchyRequestError!!exception}}" {{DOMException}}.

 <li><p>If <var>node</var> is a <a>host-including inclusive ancestor</a> of <var>parent</var>, then
 <a>throw</a> a "{{HierarchyRequestError!!exception}}" {{DOMException}}.

 <li><p>If <var>child</var>'s <a for=tree>parent</a> is not <var>parent</var>, then <a>throw</a> a
 "{{NotFoundError!!exception}}" {{DOMException}}.

 <li><p>If <var>node</var> is not a {{DocumentFragment}}, {{DocumentType}}, {{Element}}, {{Text}},
 {{ProcessingInstruction}}, or {{Comment}} <a>node</a>, then <a>throw</a> a
 "{{HierarchyRequestError!!exception}}" {{DOMException}}.

 <li><p>If either <var>node</var> is a {{Text}} <a>node</a> and <var>parent</var> is a
 <a>document</a>, or <var>node</var> is a <a>doctype</a> and <var>parent</var> is not a
 <a>document</a>, then <a>throw</a> a "{{HierarchyRequestError!!exception}}" {{DOMException}}.

 <li>
  <p>If <var>parent</var> is a <a>document</a>, and any of the statements below, switched on
  <var>node</var>, are true, then <a>throw</a> a
  "{{HierarchyRequestError!!exception}}" {{DOMException}}.

  <dl class=switch>
   <dt>{{DocumentFragment}} <a>node</a>
   <dd>
    <p>If <var>node</var> has more than one <a for="/">element</a> <a for=tree>child</a> or has a
    {{Text}} <a>node</a> <a for=tree>child</a>.

    <p>Otherwise, if <var>node</var> has one <a for="/">element</a> <a for=tree>child</a> and either
    <var>parent</var> has an <a for="/">element</a> <a for=tree>child</a> that is not
    <var>child</var> or a <a>doctype</a> is <a>following</a> <var>child</var>.

   <dt><a for="/">element</a>
   <dd><p><var>parent</var> has an <a for="/">element</a> <a for=tree>child</a> that is not
   <var>child</var> or a <a>doctype</a> is <a>following</a> <var>child</var>.

   <dt><a>doctype</a>
   <dd><p><var>parent</var> has a <a>doctype</a> <a for=tree>child</a> that is not <var>child</var>,
   or an <a for="/">element</a> is <a>preceding</a> <var>child</var>.
  </dl>

  <p class="note no-backref">The above statements differ from the <a>pre-insert</a> algorithm.

 <li><p>Let <var>referenceChild</var> be <var>child</var>'s <a for=tree>next sibling</a>.

 <li><p>If <var>referenceChild</var> is <var>node</var>, then set <var>referenceChild</var> to
 <var>node</var>'s <a for=tree>next sibling</a>.

 <li><p>Let <var>previousSibling</var> be <var>child</var>'s <a>previous sibling</a>.

 <li><p>Let <var>removedNodes</var> be the empty list.

 <li>
  <p>If <var>child</var>'s <a for=tree>parent</a> is non-null, then:

  <ol>
   <li><p>Set <var>removedNodes</var> to « <var>child</var> ».

   <li><p><a for=/>Remove</a> <var>child</var> with the <i>suppress observers flag</i> set.
  </ol>

  <p class="note no-backref">The above can only be false if <var>child</var> is <var>node</var>.

 <li><p>Let <var>nodes</var> be <var>node</var>'s <a>children</a> if <var>node</var> is a
 {{DocumentFragment}} <a>node</a>; otherwise « <var>node</var> ».
 <!-- This needs to come before insert as that removes the children of a
      DocumentFragment node. -->

 <li><p><a for=/>Insert</a> <var>node</var> into <var>parent</var> before <var>referenceChild</var>
 with the <i>suppress observers flag</i> set.

 <li><p><a>Queue a tree mutation record</a> for <var>parent</var> with <var>nodes</var>,
 <var>removedNodes</var>, <var>previousSibling</var>, and <var>referenceChild</var>.

 <li><p>Return <var>child</var>.
</ol>


<p>To <dfn export for=Node id=concept-node-replace-all>replace all</dfn> with a <var>node</var>
within a <var>parent</var>, run these steps:

<ol>
 <li><p>Let <var>removedNodes</var> be <var>parent</var>'s <a>children</a>.

 <li><p>Let <var>addedNodes</var> be the empty list.

 <li><p>If <var>node</var> is {{DocumentFragment}} <a>node</a>, then set <var>addedNodes</var> to
 <var>node</var>'s <a>children</a>.

 <li><p>Otherwise, if <var>node</var> is non-null, set <var>addedNodes</var> to « <var>node</var> ».

 <li><p><a for=/>Remove</a> all <var>parent</var>'s <a>children</a>, in <a>tree order</a>, with the
 <i>suppress observers flag</i> set.

 <li><p>If <var>node</var> is non-null, then <a for=/>insert</a> <var>node</var> into
 <var>parent</var> before null with the <i>suppress observers flag</i> set.

 <li><p><a>Queue a tree mutation record</a> for <var>parent</var> with <var>addedNodes</var>,
 <var>removedNodes</var>, null, and null.
</ol>

<p class="note no-backref">This algorithm does not make any checks with regards to the
<a>node tree</a> constraints. Specification authors need to use it wisely.


<p>To <dfn export id=concept-node-pre-remove>pre-remove</dfn> a <var>child</var> from a
<var>parent</var>, run these steps:

<ol>
 <li><p>If <var>child</var>'s <a for=tree>parent</a> is not <var>parent</var>, then <a>throw</a> a
 "{{NotFoundError!!exception}}" {{DOMException}}.

 <li><p><a for=/>Remove</a> <var>child</var>.

 <li><p>Return <var>child</var>.
 <!-- Technically this is post-remove. -->
</ol>


<p><a lt="Other applicable specifications">Specifications</a> may define
<dfn export id=concept-node-remove-ext>removing steps</dfn> for all or some <a for=/>nodes</a>. The
algorithm is passed <var ignore>removedNode</var>, and optionally <var ignore>oldParent</var>, as
indicated in the <a for=/>remove</a> algorithm below.

<p>To <dfn export id=concept-node-remove>remove</dfn> a <var>node</var>, with an optional
<i>suppress observers flag</i>, run these steps:

<ol>
 <li><p>Let <var>parent</var> be <var>node</var>'s <a for=tree>parent</a>

 <li><p>Assert: <var>parent</var> is non-null.

 <li><p>Let <var>index</var> be <var>node</var>'s <a for=tree>index</a>.

 <li><p>For each <a>live range</a> whose <a for=range>start node</a> is an
 <a>inclusive descendant</a> of <var>node</var>, set its <a for=range>start</a> to
 (<var>parent</var>, <var>index</var>).

 <li><p>For each <a>live range</a> whose <a for=range>end node</a> is an <a>inclusive descendant</a>
 of <var>node</var>, set its <a for=range>end</a> to (<var>parent</var>, <var>index</var>).

 <li><p>For each <a>live range</a> whose <a for=range>start node</a> is <var>parent</var> and
 <a for=range>start offset</a> is greater than <var>index</var>, decrease its
 <a for=range>start offset</a> by 1.

 <li><p>For each <a>live range</a> whose <a for=range>end node</a> is <var>parent</var> and
 <a for=range>end offset</a> is greater than <var>index</var>, decrease its
 <a for=range>end offset</a> by 1.

 <li><p>For each {{NodeIterator}} object <var>iterator</var> whose
 <a for=traversal>root</a>'s <a for=Node>node document</a> is <var>node</var>'s
 <a for=Node>node document</a>, run the <a><code>NodeIterator</code> pre-removing steps</a> given
 <var>node</var> and <var>iterator</var>.

 <li><p>Let <var>oldPreviousSibling</var> be <var>node</var>'s <a>previous sibling</a>.

 <li><p>Let <var>oldNextSibling</var> be <var>node</var>'s <a for=tree>next sibling</a>.

 <li><p><a for=set>Remove</a> <var>node</var> from its <var>parent</var>'s <a for=tree>children</a>.

 <li><p>If <var>node</var> is <a for=slotable>assigned</a>, then run <a>assign slotables</a> for
 <var>node</var>'s <a>assigned slot</a>.

 <li><p>If <var>parent</var>'s <a for=tree>root</a> is a <a for=/>shadow root</a>, and
 <var>parent</var> is a <a>slot</a> whose <a for=slot>assigned nodes</a> is the empty list,
 then run <a>signal a slot change</a> for <var>parent</var>.

 <li>
  <p>If <var>node</var> has an <a>inclusive descendant</a> that is a <a>slot</a>, then:

  <ol>
   <li><p>Run <a>assign slotables for a tree</a> with <var>parent</var>'s <a for=tree>root</a>.

   <li><p>Run <a>assign slotables for a tree</a> with <var>node</var>.
  </ol>

 <li><p>Run the <a>removing steps</a> with <var>node</var> and <var>parent</var>.

 <li>
  <p>If <var>node</var> is <a for=Element>custom</a>, then
  <a>enqueue a custom element callback reaction</a> with <var>node</var>, callback name
  "<code>disconnectedCallback</code>", and an empty argument list.

  <p class=note>It is intentional for now that <a for=Element>custom</a> <a for=/>elements</a> do
  not get <var>parent</var> passed. This might change in the future if there is a need.

 <li>
  <p>For each <a>shadow-including descendant</a> <var>descendant</var> of <var>node</var>, in
  <a>shadow-including tree order</a>, then:

  <ol>
   <li><p>Run the <a>removing steps</a> with <var>descendant</var>.

   <li><p>If <var>descendant</var> is <a for=Element>custom</a>, then
   <a>enqueue a custom element callback reaction</a> with <var>descendant</var>, callback name
   "<code>disconnectedCallback</code>", and an empty argument list.
  </ol>
 </li>

 <li><p>For each <a for=tree>inclusive ancestor</a> <var>inclusiveAncestor</var> of
 <var>parent</var>, and then <a for=list>for each</a> <var>registered</var> of
 <var>inclusiveAncestor</var>'s <a>registered observer list</a>, if <var>registered</var>'s
 <a for="registered observer">options</a>'s {{MutationObserverInit/subtree}} is true, then
 <a for=list>append</a> a new <a>transient registered observer</a> whose
 <a for="registered observer">observer</a> is <var>registered</var>'s
 <a for="registered observer">observer</a>, <a for="registered observer">options</a> is
 <var>registered</var>'s <a for="registered observer">options</a>, and
 <a for="transient registered observer">source</a> is <var>registered</var> to <var>node</var>'s
 <a>registered observer list</a>.

 <li><p>If <i>suppress observers flag</i> is unset, then <a>queue a tree mutation record</a> for
 <var>parent</var> with « », « <var>node</var> », <var>oldPreviousSibling</var>, and
 <var>oldNextSibling</var>.

 <li><p>Run the <a>children changed steps</a> for <var>parent</var>.
</ol>


<h4 id=interface-nonelementparentnode>Mixin {{NonElementParentNode}}</h4>

<p class="note no-backref">Web compatibility prevents the {{NonElementParentNode/getElementById()}}
method from being exposed on <a for="/">elements</a> (and therefore on {{ParentNode}}).

<pre class=idl>
interface mixin NonElementParentNode {
  Element? getElementById(DOMString elementId);
};
Document includes NonElementParentNode;
DocumentFragment includes NonElementParentNode;
</pre>

<dl class=domintro>
 <dt><code><var>node</var> . <a method for=NonElementParentNode lt="getElementById()">getElementById</a>(<var>elementId</var>)</code>
 <dd><p>Returns the first <a for="/">element</a> within <var>node</var>'s <a>descendants</a> whose
 <a for=Element>ID</a> is <var>elementId</var>.
</dl>

<p>The <dfn method for=NonElementParentNode><code>getElementById(<var>elementId</var>)</code></dfn>
method, when invoked, must return the first <a for="/">element</a>, in <a>tree order</a>, within the
<a>context object</a>'s <a>descendants</a>, whose <a for=Element>ID</a> is <var>elementId</var>, and
null if there is no such <a for="/">element</a> otherwise.


<h4 id=mixin-documentorshadowroot>Mixin {{DocumentOrShadowRoot}}</h4>

<pre class=idl>
interface mixin DocumentOrShadowRoot {
};
Document includes DocumentOrShadowRoot;
ShadowRoot includes DocumentOrShadowRoot;
</pre>

<p class="note no-backref">The {{DocumentOrShadowRoot}} mixin is expected to be used by other
standards that want to define APIs shared between <a for=/>documents</a> and
<a for=/>shadow roots</a>.


<h4 id=interface-parentnode>Mixin {{ParentNode}}</h4>

<p>To <dfn export lt="converting nodes into a node">convert nodes into a node</dfn>, given
<var>nodes</var> and <var>document</var>, run these steps:

<ol>
 <li><p>Let <var>node</var> be null.

 <li><p>Replace each string in <var>nodes</var> with a new {{Text}} <a>node</a> whose
 <a for=CharacterData>data</a> is the string and <a for=Node>node document</a> is
 <var>document</var>.

 <li><p>If <var>nodes</var> contains one <a>node</a>, set <var>node</var> to that
 <a>node</a>.

 <li><p>Otherwise, set <var>node</var> to a new {{DocumentFragment}} whose
 <a for=Node>node document</a> is <var>document</var>, and then <a>append</a> each <a>node</a> in
 <var>nodes</var>, if any, to it.

 <li><p>Return <var>node</var>.
</ol>

<pre class=idl>
interface mixin ParentNode {
  [SameObject] readonly attribute HTMLCollection children;
  readonly attribute Element? firstElementChild;
  readonly attribute Element? lastElementChild;
  readonly attribute unsigned long childElementCount;

  [CEReactions, Unscopable] void prepend((Node or DOMString)... nodes);
  [CEReactions, Unscopable] void append((Node or DOMString)... nodes);

  Element? querySelector(DOMString selectors);
  [NewObject] NodeList querySelectorAll(DOMString selectors);
};
Document includes ParentNode;
DocumentFragment includes ParentNode;
Element includes ParentNode;
</pre>

<dl class=domintro>
 <dt><code><var>collection</var> = <var>node</var> . {{ParentNode/children}}</code>
 <dd>Returns the <a for=tree>child</a> <a for="/">elements</a>.

 <dt><code><var>element</var> = <var>node</var> . {{ParentNode/firstElementChild}}</code>
 <dd>Returns the first <a for=tree>child</a> that is an <a for="/">element</a>, and null otherwise.

 <dt><code><var>element</var> = <var>node</var> . {{ParentNode/lastElementChild}}</code>
 <dd>Returns the last <a for=tree>child</a> that is an <a for="/">element</a>, and null otherwise.

 <!-- childElementCount is redundant -->

 <dt><code><var>node</var> . <a method for=ParentNode lt="prepend()">prepend</a>(<var>nodes</var>)</code>
 <dd>
  <p>Inserts <var>nodes</var> before the <a for=tree>first child</a> of <var>node</var>, while
  replacing strings in <var>nodes</var> with equivalent {{Text}} <a for=/>nodes</a>.

  <p><a>Throws</a> a "{{HierarchyRequestError!!exception}}" {{DOMException}} if the constraints of
  the <a>node tree</a> are violated.
  <!-- "NotFoundError" is impossible -->

 <dt><code><var>node</var> . <a method for=ParentNode lt="append()">append</a>(<var>nodes</var>)</code>
 <dd>
  <p>Inserts <var>nodes</var> after the <a>last child</a> of <var>node</var>, while replacing
  strings in <var>nodes</var> with equivalent {{Text}} <a for=/>nodes</a>.

  <p><a>Throws</a> a "{{HierarchyRequestError!!exception}}" {{DOMException}} if the constraints of
  the <a>node tree</a> are violated.
  <!-- "NotFoundError" is impossible -->

 <dt><code><var>node</var> . <a method for=ParentNode lt="querySelector()">querySelector</a>(<var>selectors</var>)</code>
 <dd>
  Returns the first <a for="/">element</a> that is a
  <a>descendant</a> of <var>node</var> that
  matches <var>selectors</var>.

 <dt><code><var>node</var> . <a method for=ParentNode lt="querySelectorAll()">querySelectorAll</a>(<var>selectors</var>)</code>
 <dd>
  Returns all <a for="/">element</a>
  <a>descendants</a> of <var>node</var> that
  match <var>selectors</var>.
</dl>

<p>The <dfn attribute for=ParentNode><code>children</code></dfn> attribute's getter must return an
{{HTMLCollection}} <a>collection</a> rooted at <a>context object</a> matching only
<a for="/">element</a> <a>children</a>.

<p>The <dfn attribute for=ParentNode><code>firstElementChild</code></dfn> attribute's getter must
return the first <a for=tree>child</a> that is an <a for="/">element</a>, and null otherwise.

<p>The <dfn attribute for=ParentNode><code>lastElementChild</code></dfn> attribute's getter must
return the last <a for=tree>child</a> that is an <a for="/">element</a>, and null otherwise.

<p>The <dfn attribute for=ParentNode><code>childElementCount</code></dfn> attribute's getter must
return the number of <a>children</a> of <a>context object</a> that are <a for="/">elements</a>.

<p>The <dfn method for=ParentNode><code>prepend(<var>nodes</var>)</code></dfn> method, when invoked,
must run these steps:

<ol>
 <li><p>Let <var>node</var> be the result of <a>converting nodes into a node</a> given
 <var>nodes</var> and <a>context object</a>'s <a for=Node>node document</a>.

 <li><p><a>Pre-insert</a> <var>node</var> into <a>context object</a> before the
 <a>context object</a>'s <a for=tree>first child</a>.
</ol>

<p>The <dfn method for=ParentNode><code>append(<var>nodes</var>)</code></dfn> method, when invoked,
must run these steps:

<ol>
 <li><p>Let <var>node</var> be the result of <a>converting nodes into a node</a> given
 <var>nodes</var> and <a>context object</a>'s <a for=Node>node document</a>.

 <li><p><a>Append</a> <var>node</var> to <a>context object</a>.
</ol>

<p>The <dfn method for=ParentNode><code>querySelector(<var>selectors</var>)</code></dfn> method,
when invoked, must return the first result of running <a>scope-match a selectors string</a>
<var>selectors</var> against <a>context object</a>, if the result is not an empty list, and null
otherwise.

<p>The <dfn method for=ParentNode><code>querySelectorAll(<var>selectors</var>)</code></dfn>
method, when invoked, must return the <a lt="static collection">static</a> result of running
<a>scope-match a selectors string</a> <var>selectors</var> against <a>context object</a>.


<h4 id=interface-nondocumenttypechildnode>Mixin {{NonDocumentTypeChildNode}}</h4>

<p class="note no-backref">Web compatibility prevents the {{previousElementSibling}} and
{{nextElementSibling}} attributes from being exposed on <a for=/>doctypes</a> (and therefore on
{{ChildNode}}).

<pre class=idl>
interface mixin NonDocumentTypeChildNode {
  readonly attribute Element? previousElementSibling;
  readonly attribute Element? nextElementSibling;
};
Element includes NonDocumentTypeChildNode;
CharacterData includes NonDocumentTypeChildNode;
</pre>

<dl class=domintro>
 <dt><code><var>element</var> = <var>node</var> . {{previousElementSibling}}</code>
 <dd>Returns the first
 <a>preceding</a>
 <a for=tree>sibling</a> that
 is an <a for="/">element</a>, and null otherwise.

 <dt><code><var>element</var> = <var>node</var> . {{nextElementSibling}}</code>
 <dd>Returns the first
 <a>following</a>
 <a for=tree>sibling</a> that
 is an <a for="/">element</a>, and null otherwise.
</dl>

<p>The <dfn attribute for=NonDocumentTypeChildNode><code>previousElementSibling</code></dfn>
attribute's getter must return the first <a>preceding</a> <a for=tree>sibling</a> that is an
<a for="/">element</a>, and null otherwise.

<p>The <dfn attribute for=NonDocumentTypeChildNode><code>nextElementSibling</code></dfn> attribute's
getter must return the first <a>following</a> <a for=tree>sibling</a> that is an
<a for=/>element</a>, and null otherwise.


<h4 id=interface-childnode>Mixin {{ChildNode}}</h4>

<pre class=idl>
interface mixin ChildNode {
  [CEReactions, Unscopable] void before((Node or DOMString)... nodes);
  [CEReactions, Unscopable] void after((Node or DOMString)... nodes);
  [CEReactions, Unscopable] void replaceWith((Node or DOMString)... nodes);
  [CEReactions, Unscopable] void remove();
};
DocumentType includes ChildNode;
Element includes ChildNode;
CharacterData includes ChildNode;
</pre>

<dl class=domintro>
 <dt><code><var>node</var> . {{before(...nodes)}}</code>
 <dd>
  <p>Inserts <var>nodes</var> just before <var>node</var>, while replacing strings in
  <var>nodes</var> with equivalent {{Text}} <a for=/>nodes</a>.

  <p><a>Throws</a> a "{{HierarchyRequestError!!exception}}" {{DOMException}} if the constraints of
  the <a>node tree</a> are violated.

 <dt><code><var>node</var> . {{after(...nodes)}}</code>
 <dd>
  <p>Inserts <var>nodes</var> just after <var>node</var>, while replacing strings in
  <var>nodes</var> with equivalent {{Text}} <a for=/>nodes</a>.

  <p><a>Throws</a> a "{{HierarchyRequestError!!exception}}" {{DOMException}} if the constraints of
  the <a>node tree</a> are violated.

 <dt><code><var>node</var> . {{replaceWith(...nodes)}}</code>
 <dd>
  <p>Replaces <var>node</var> with <var>nodes</var>, while replacing strings in <var>nodes</var>
  with equivalent {{Text}} <a for=/>nodes</a>.

  <p><a>Throws</a> a "{{HierarchyRequestError!!exception}}" {{DOMException}} if the constraints of
  the <a>node tree</a> are violated.

 <dt><code><var>node</var> . {{ChildNode/remove()}}</code>
 <dd>Removes <var>node</var>.
</dl>

<p>The <dfn method for=ChildNode><code>before(<var>nodes</var>)</code></dfn> method, when invoked,
must run these steps:

<ol>
 <li><p>Let <var>parent</var> be <a>context object</a>'s <a for=tree>parent</a>.

 <li><p>If <var>parent</var> is null, then return.

 <li><p>Let <var>viablePreviousSibling</var> be <a>context object</a>'s first
 <a>preceding</a> <a for=tree>sibling</a> not in <var>nodes</var>, and null otherwise.

 <li><p>Let <var>node</var> be the result of <a>converting nodes into a node</a>, given
 <var>nodes</var> and <a>context object</a>'s <a for=Node>node document</a>.

 <li><p>If <var>viablePreviousSibling</var> is null, set it to <var>parent</var>'s
 <a for=tree>first child</a>, and to <var>viablePreviousSibling</var>'s <a for=tree>next sibling</a>
 otherwise.

 <li><p><a>Pre-insert</a> <var>node</var> into <var>parent</var> before
 <var>viablePreviousSibling</var>.
</ol>

<p>The <dfn method for=ChildNode><code>after(<var>nodes</var>)</code></dfn> method, when invoked,
must run these steps:

<ol>
 <li><p>Let <var>parent</var> be <a>context object</a>'s <a for=tree>parent</a>.

 <li><p>If <var>parent</var> is null, then return.

 <li><p>Let <var>viableNextSibling</var> be <a>context object</a>'s first <a>following</a>
 <a for=tree>sibling</a> not in <var>nodes</var>, and null otherwise.

 <li><p>Let <var>node</var> be the result of <a>converting nodes into a node</a>, given
 <var>nodes</var> and <a>context object</a>'s <a for=Node>node document</a>.

 <li><p><a>Pre-insert</a> <var>node</var> into <var>parent</var> before
 <var>viableNextSibling</var>.
</ol>

<p>The <dfn method for=ChildNode><code>replaceWith(<var>nodes</var>)</code></dfn> method, when
invoked, must run these steps:

<ol>
 <li><p>Let <var>parent</var> be <a>context object</a>'s <a for=tree>parent</a>.

 <li><p>If <var>parent</var> is null, then return.

 <li><p>Let <var>viableNextSibling</var> be <a>context object</a>'s first <a>following</a>
 <a for=tree>sibling</a> not in <var>nodes</var>, and null otherwise.

 <li><p>Let <var>node</var> be the result of <a>converting nodes into a node</a>, given
 <var>nodes</var> and <a>context object</a>'s <a for=Node>node document</a>.

 <li>
  <p>If <a>context object</a>'s <a for=tree>parent</a> is <var>parent</var>, <a>replace</a> the
  <a>context object</a> with <var>node</var> within <var>parent</var>.

  <p class=note><a>Context object</a> could have been inserted into <var>node</var>.

 <li><p>Otherwise, <a>pre-insert</a> <var>node</var> into <var>parent</var> before
 <var>viableNextSibling</var>.
</ol>

<p>The <dfn method for=ChildNode><code>remove()</code></dfn> method, when invoked, must run these
steps:

<ol>
 <li><p>If <a>context object</a>'s <a for=tree>parent</a> is null, then return.

 <li><p><a for=/>Remove</a> the <a>context object</a>.
</ol>


<h4 id=mixin-slotable>Mixin {{Slotable}}</h4>

<pre class=idl>
interface mixin Slotable {
  readonly attribute HTMLSlotElement? assignedSlot;
};
Element includes Slotable;
Text includes Slotable;
</pre>

<p>The <dfn attribute for=Slotable><code>assignedSlot</code></dfn> attribute's getter must return
the result of <a>find a slot</a> given <a>context object</a> and with the <i>open flag</i> set.</p>


<h4 id=old-style-collections>Old-style collections: {{NodeList}} and {{HTMLCollection}}</h4>

A <dfn export id=concept-collection>collection</dfn> is an object that represents a list of
<a for=/>nodes</a>. A <a>collection</a> can be either
<dfn export for=collection id=concept-collection-live lt="live collection" local-lt="live">live</dfn>
or <dfn export for=collection id=concept-collection-static lt="static collection">static</dfn>.
Unless otherwise stated, a <a>collection</a> must be <a for=collection>live</a>.

If a <a>collection</a> is <a for=collection>live</a>, then the attributes and methods
on that object must operate on the actual underlying data, not a snapshot of
the data.

When a <a>collection</a> is created, a
filter and a root are associated with it.

The <a>collection</a> then
<dfn export for=collection lt="represented by the collection" id=represented-by-the-collection>represents</dfn>
a view of the subtree rooted at the <a>collection's</a> root, containing only nodes that match the
given filter. The view is linear. In the absence of specific requirements to the contrary, the nodes
within the <a>collection</a> must be sorted in <a>tree order</a>.


<h5 id=interface-nodelist>Interface {{NodeList}}</h5>

<p>A {{NodeList}} object is a <a>collection</a> of <a for=/>nodes</a>.

<pre class=idl>
[Exposed=Window]
interface NodeList {
  getter Node? item(unsigned long index);
  readonly attribute unsigned long length;
  iterable&lt;Node>;
};
</pre>

<dl class=domintro>
 <dt><var>collection</var> . {{NodeList/length}}
 <dd>Returns the number of <a for=/>nodes</a> in the <a>collection</a>.

 <dt><var>element</var> = <var>collection</var> . {{NodeList/item(index)}}
 <dt><var>element</var> = <var>collection</var>[<var>index</var>]
 <dd>Returns the <a>node</a> with index <var>index</var> from the <a>collection</a>. The
 <a for=/>nodes</a> are sorted in <a>tree order</a>.
</dl>

<div class=impl>

<p>The object's <a>supported property indices</a> are the numbers in the range zero to one less than
the number of nodes <a for=collection>represented by the collection</a>. If there are no such
elements, then there are no <a>supported property indices</a>.

<p>The <dfn attribute for=NodeList>length</dfn> attribute must return the number of nodes
<a for=collection>represented by the collection</a>.

<p>The <dfn method for=NodeList><code>item(<var>index</var>)</code></dfn> method must return the
<var>index</var><sup>th</sup> <a>node</a> in the <a>collection</a>. If there is no
<var>index</var><sup>th</sup> <a>node</a> in the <a>collection</a>, then the method must return
null.

</div>


<h5 id=interface-htmlcollection>Interface {{HTMLCollection}}</h5>

<pre class=idl>
[Exposed=Window, LegacyUnenumerableNamedProperties]
interface HTMLCollection {
  readonly attribute unsigned long length;
  getter Element? item(unsigned long index);
  getter Element? namedItem(DOMString name);
};
</pre>

<p>An {{HTMLCollection}} object is a <a>collection</a> of <a for="/">elements</a>.

<p class="note no-backref">{{HTMLCollection}} is a historical artifact we cannot rid the web of.
While developers are of course welcome to keep using it, new API standard designers ought not to use
it (use <code>sequence&lt;T></code> in IDL instead).

<dl class=domintro>
 <dt><var>collection</var> . {{HTMLCollection/length}}
 <dd>
  Returns the number of <a for="/">elements</a> in
  the <a>collection</a>.

 <dt><var>element</var> = <var>collection</var> . {{HTMLCollection/item(index)}}
 <dt><var>element</var> = <var>collection</var>[<var>index</var>]
 <dd>
  Returns the <a for="/">element</a> with index
  <var>index</var> from the <a>collection</a>.
  The <a for="/">elements</a> are sorted in <a>tree order</a>.

 <dt><var>element</var> = <var>collection</var> . {{namedItem(name)}}
 <dt><var>element</var> = <var>collection</var>[<var>name</var>]
 <dd>
  Returns the first <a for="/">element</a> with <a for=Element>ID</a> or name <var>name</var>
  from the collection.
</dl>

<p>The object's <a>supported property indices</a> are the numbers in the range zero to one less than
the number of elements <a for=collection>represented by the collection</a>. If there are no such
elements, then there are no <a>supported property indices</a>.

<p>The <dfn attribute for=HTMLCollection><code>length</code></dfn> attribute's getter must return
the number of nodes <a for=collection>represented by the collection</a>.

<p>The <dfn method for=HTMLCollection><code>item(<var>index</var>)</code></dfn> method, when
invoked, must return the <var>index</var><sup>th</sup> <a for="/">element</a> in the
<a>collection</a>. If there is no <var>index</var><sup>th</sup> <a for="/">element</a> in the
<a>collection</a>, then the method must return null.

<p>The <a>supported property names</a> are the values from the list returned by these steps:

<ol>
 <li><p>Let <var>result</var> be an empty list.

 <li>
  <p>For each <var>element</var> <a for=collection>represented by the collection</a>, in
  <a>tree order</a>:

  <ol>
   <li><p>If <var>element</var> has an <a for=Element>ID</a> which is not in <var>result</var>,
   append <var>element</var>'s <a for=Element>ID</a> to <var>result</var>.

   <li><p>If <var>element</var> is in the <a>HTML namespace</a> and <a lt="has an attribute">has</a>
   a <a lt="named attribute"><code>name</code> attribute</a> whose <a for=Attr>value</a> is neither
   the empty string nor is in <var>result</var>, append <var>element</var>'s
   <a lt="named attribute"><code>name</code> attribute</a> <a for=Attr>value</a> to
   <var>result</var>.
  </ol>

 <li><p>Return <var>result</var>.
</ol>

<p>The <dfn method for=HTMLCollection><code>namedItem(<var>key</var>)</code></dfn> method, when
invoked, must run these steps:

<ol>
 <li><p>If <var>key</var> is the empty string, return null.

 <li>
  <p>Return the first <a for="/">element</a> in the <a>collection</a> for which at least one of
  the following is true:

  <ul>
   <li>it has an <a for=Element>ID</a> which is <var>key</var>;

   <li>it is in the <a>HTML namespace</a> and <a lt="has an attribute">has</a> a
   <a lt="named attribute"><code>name</code> attribute</a> whose <a for=Attr>value</a> is
   <var>key</var>;
  </ul>

  <p>or null if there is no such <a for="/">element</a>.
</ol>



<h3 id=mutation-observers>Mutation observers</h3>

<p>Each <a>similar-origin window agent</a> has a
<dfn noexport id=mutation-observer-compound-microtask-queued-flag>mutation observer microtask queued</dfn>
(a boolean), which is initially false. [[!HTML]]

<p>Each <a>similar-origin window agent</a> also has
<dfn noexport id=mutation-observer-list>mutation observers</dfn> (a <a for=/>set</a> of zero or more
{{MutationObserver}} objects), which is initially empty.

<p>To
<dfn noexport id=queue-a-mutation-observer-compound-microtask>queue a mutation observer microtask</dfn>,
run these steps:

<ol>
 <li><p>If the <a>surrounding agent</a>'s <a>mutation observer microtask queued</a> is true, then
 return.

 <li><p>Set the <a>surrounding agent</a>'s <a>mutation observer microtask queued</a> to true.

 <li><p><a lt="queue a microtask">Queue</a> a <a>microtask</a> to <a>notify mutation observers</a>.
</ol>

<p>To <dfn export>notify mutation observers</dfn>, run these steps:

<ol>
 <li><p>Set the <a>surrounding agent</a>'s <a>mutation observer microtask queued</a> to false.

 <li><p>Let <var>notifySet</var> be a <a for=set>clone</a> of the <a>surrounding agent</a>'s
 <a>mutation observers</a>.

 <li><p>Let <var>signalSet</var> be a <a for=set>clone</a> of the <a>surrounding agent</a>'s
 <a>signal slots</a>.

 <li><p><a for=set>Empty</a> the <a>surrounding agent</a>'s <a>signal slots</a>.

 <li>
  <p><a for=set>For each</a> <var>mo</var> of <var>notifySet</var>:

  <ol>
   <li><p>Let <var>records</var> be a <a for=queue>clone</a> of <var>mo</var>'s
   <a for=MutationObserver>record queue</a>.

   <li><p><a for=queue>Empty</a> <var>mo</var>'s <a for=MutationObserver>record queue</a>.

   <li><p><a for=list>For each</a> <var>node</var> of <var>mo</var>'s
   <a for=MutationObserver>node list</a>, <a for=list>remove</a> all
   <a>transient registered observers</a> whose <a for="registered observer">observer</a> is
   <var>mo</var> from <var>node</var>'s <a>registered observer list</a>.

   <li><p>If <var>records</var> <a for=queue>is not empty</a>, then <a spec=webidl>invoke</a>
   <var>mo</var>'s <a for=MutationObserver>callback</a> with « <var>records</var>, <var>mo</var> »,
   and <var>mo</var>. If this throws an exception, then <a>report the exception</a>.
  </ol>

 <li><p><a for=set>For each</a> <var>slot</var> of <var>signalSet</var>, <a>fire an event</a>
 named {{HTMLSlotElement/slotchange}}, with its {{Event/bubbles}} attribute set to true, at
 <var>slot</var>.
</ol>

<hr>

<p>Each <a for=/>node</a> has a <dfn noexport>registered observer list</dfn> (a <a for=/>list</a> of
zero or more <a>registered observers</a>), which is initially empty.

<p>A <dfn noexport id=registered-observer>registered observer</dfn> consists of an
<dfn noexport for="registered observer">observer</dfn> (a {{MutationObserver}} object) and
<dfn noexport for="registered observer">options</dfn> (a {{MutationObserverInit}} dictionary).

<p>A <dfn noexport id=transient-registered-observer>transient registered observer</dfn> is a
<a>registered observer</a> that also consists of a
<dfn for="transient registered observer">source</dfn> (a <a>registered observer</a>).

<p class="note no-backref"><a>Transient registered observers</a> are used to track mutations within
a given <a for=/>node</a>'s <a for=tree>descendants</a> after <a for=/>node</a> has been removed so
they do not get lost when {{MutationObserverInit/subtree}} is set to true on <a for=/>node</a>'s
<a for=tree>parent</a>.


<h4 id=interface-mutationobserver>Interface {{MutationObserver}}</h4>

<pre class="idl">
[Exposed=Window]
interface MutationObserver {
  constructor(MutationCallback callback);

  void observe(Node target, optional MutationObserverInit options = {});
  void disconnect();
  sequence&lt;MutationRecord> takeRecords();
};

callback MutationCallback = void (sequence&lt;MutationRecord> mutations, MutationObserver observer);

dictionary MutationObserverInit {
  boolean childList = false;
  boolean attributes;
  boolean characterData;
  boolean subtree = false;
  boolean attributeOldValue;
  boolean characterDataOldValue;
  sequence&lt;DOMString> attributeFilter;
};
</pre>

<p>A {{MutationObserver}} object can be used to observe mutations to the <a>tree</a> of
<a for=/>nodes</a>.

<p>Each {{MutationObserver}} object has these associated concepts:

<ul>
 <li>A <dfn noexport for=MutationObserver id=concept-mo-callback>callback</dfn> set on creation.
 <li>A <dfn noexport for=MutationObserver>node list</dfn> (a <a for=/>list</a> of
 <a for=/>nodes</a>), which is initially empty.
 <li>A <dfn export for=MutationObserver id=concept-mo-queue>record queue</dfn> (a <a for=/>queue</a>
 of zero or more {{MutationRecord}} objects), which is initially empty.
</ul>

<dl class=domintro>
 <dt><code><var>observer</var> = new {{MutationObserver(callback)}}</code>
 <dd>Constructs a {{MutationObserver}} object and sets its <a for=MutationObserver>callback</a> to
 <var>callback</var>. The <var>callback</var> is invoked with a list of {{MutationRecord}} objects
 as first argument and the constructed {{MutationObserver}} object as second argument. It is
 invoked after <a for=/>nodes</a> registered with the {{MutationObserver/observe()}} method, are
 mutated.

 <dt><code><var>observer</var> . {{observe(target, options)}}</code>
 <dd>
  Instructs the user agent to observe a given <var>target</var>
  (a <a>node</a>) and report any mutations based on
  the criteria given by <var>options</var> (an object).

  The <var>options</var> argument allows for setting mutation
  observation options via object members. These are the object members that
  can be used:

  <dl>
   <dt>{{MutationObserverInit/childList}}
   <dd>Set to true if mutations to <var>target</var>'s <a>children</a> are to be observed.

   <dt>{{MutationObserverInit/attributes}}
   <dd>Set to true if mutations to <var>target</var>'s
   <a>attributes</a> are to be observed. Can be omitted if
   {{MutationObserverInit/attributeOldValue}} or
   {{MutationObserverInit/attributeFilter}} is
   specified.

   <dt>{{MutationObserverInit/characterData}}
   <dd>Set to true if mutations to <var>target</var>'s
   <a for=CharacterData>data</a> are to be observed. Can be omitted if
   {{MutationObserverInit/characterDataOldValue}}
   is specified.

   <dt>{{MutationObserverInit/subtree}}
   <dd>Set to true if mutations to not just <var>target</var>, but
   also <var>target</var>'s
   <a>descendants</a> are to be
   observed.

   <dt>{{MutationObserverInit/attributeOldValue}}
   <dd>Set to true if
   {{MutationObserverInit/attributes}} is true or omitted
   and <var>target</var>'s
   <a>attribute</a>
   <a for=Attr>value</a> before the mutation
   needs to be recorded.

   <dt>{{MutationObserverInit/characterDataOldValue}}
   <dd>Set to true if
   {{MutationObserverInit/characterData}}
   is set to true or omitted and <var>target</var>'s
   <a for=CharacterData>data</a> before the mutation
   needs to be recorded.

   <dt>{{MutationObserverInit/attributeFilter}}
   <dd>Set to a list of <a>attribute</a>
   <a for=Attr>local names</a> (without <a for=Attr>namespace</a>) if not all
   <a>attribute</a> mutations need to be
   observed and {{MutationObserverInit/attributes}} is true
   or omitted.
  </dl>

 <dt><code><var>observer</var> . {{disconnect()}}</code>
 <dd>Stops <var>observer</var> from observing any mutations. Until the {{observe()}} method is used
 again, <var>observer</var>'s <a for=MutationObserver>callback</a> will not be invoked.

 <dt><code><var>observer</var> . {{takeRecords()}}</code>
 <dd>Empties the <a>record queue</a> and
 returns what was in there.
</dl>

<p>The
<dfn constructor for=MutationObserver><code>MutationObserver(<var>callback</var>)</code></dfn>
constructor, when invoked, must run these steps:

<ol>
 <li><p>Let <var>mo</var> be a new {{MutationObserver}} object whose
 <a for=MutationObserver>callback</a> is <var>callback</var>.

 <li><p><a for=set>Append</a> <var>mo</var> to <var>mo</var>'s <a>relevant agent</a>'s
 <a>mutation observers</a>.

 <li><p>Return <var>mo</var>.
</ol>

<p>The
<dfn method for=MutationObserver><code>observe(<var>target</var>, <var>options</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li><p>If either <var>options</var>'s {{MutationObserverInit/attributeOldValue}} or
 {{MutationObserverInit/attributeFilter}} is present and <var>options</var>'s
 {{MutationObserverInit/attributes}} is omitted, then set <var>options</var>'s
 {{MutationObserverInit/attributes}} to true.

 <li><p>If <var>options</var>'s {{MutationObserverInit/characterDataOldValue}} is present and
 <var>options</var>'s {{MutationObserverInit/characterData}} is omitted, then set
 <var>options</var>'s {{MutationObserverInit/characterData}} to true.

 <li><p>If none of <var>options</var>'s {{MutationObserverInit/childList}},
 {{MutationObserverInit/attributes}}, and {{MutationObserverInit/characterData}} is true, then
 <a>throw</a> a <code>TypeError</code>.

 <li><p>If <var>options</var>'s {{MutationObserverInit/attributeOldValue}} is true and
 <var>options</var>'s {{MutationObserverInit/attributes}} is false, then <a>throw</a> a
 <code>TypeError</code>.

 <li><p>If <var>options</var>'s {{MutationObserverInit/attributeFilter}} is present and
 <var>options</var>'s {{MutationObserverInit/attributes}} is false, then <a>throw</a> a
 <code>TypeError</code>.

 <li><p>If <var>options</var>'s {{MutationObserverInit/characterDataOldValue}} is true and
 <var>options</var>'s {{MutationObserverInit/characterData}} is false, then <a>throw</a> a
 <code>TypeError</code>.

 <li>
  <p><a for=list>For each</a> <var>registered</var> of <var>target</var>'s
  <a>registered observer list</a>, if <var>registered</var>'s
  <a for="registered observer">observer</a> is the <a>context object</a>:

  <ol>
   <li><p><a for=list>For each</a> <var>node</var> of the <a>context object</a>'s
   <a for=MutationObserver>node list</a>, <a for=list>remove</a> all
   <a>transient registered observers</a> whose <a for="transient registered observer">source</a> is
   <var>registered</var> from <var>node</var>'s <a>registered observer list</a>.

   <li><p>Set <var>registered</var>'s <a for="registered observer">options</a> to
   <var>options</var>.
  </ol>

 <li>
  <p>Otherwise:

  <ol>
   <li><p><a for=list>Append</a> a new <a>registered observer</a> whose
   <a for="registered observer">observer</a> is the <a>context object</a> and
   <a for="registered observer">options</a> is <var>options</var> to <var>target</var>'s
   <a>registered observer list</a>.

   <li><p><a for=list>Append</a> <var>target</var> to the <a>context object</a>'s
   <a for=MutationObserver>node list</a>.
  </ol>
</ol>

<p>The <dfn method for=MutationObserver><code>disconnect()</code></dfn> method, when invoked, must
run these steps:

<ol>
 <li><p><a for=list>For each</a> <var>node</var> of the <a>context object</a>'s
 <a for=MutationObserver>node list</a>, <a for=list>remove</a> any <a>registered observer</a> from
 <var>node</var>'s <a>registered observer list</a> for which the <a>context object</a> is the
 <a for="registered observer">observer</a>.

 <li><p><a for=queue>Empty</a> the <a>context object</a>'s <a for=MutationObserver>record queue</a>.
</ol>

<p>The <dfn method for=MutationObserver><code>takeRecords()</code></dfn> method, when invoked, must
run these steps:

<ol>
 <li><p>Let <var>records</var> be a <a for=queue>clone</a> of the <a>context object</a>'s
 <a for=MutationObserver>record queue</a>.

 <li><p><a for=queue>Empty</a> the <a>context object</a>'s <a for=MutationObserver>record queue</a>.

 <li><p>Return <var>records</var>.
</ol>


<h4 id=queueing-a-mutation-record>Queuing a mutation record</h4>

<p>To <dfn noexport>queue a mutation record</dfn> of <var>type</var> for <var>target</var> with
<var>name</var>, <var>namespace</var>, <var>oldValue</var>, <var>addedNodes</var>,
<var>removedNodes</var>, <var>previousSibling</var>, and <var>nextSibling</var>, run these steps:

<ol>
 <li><p>Let <var>interestedObservers</var> be an empty <a for=/>map</a>.

 <li><p>Let <var>nodes</var> be the <a for=tree>inclusive ancestors</a> of <var>target</var>.

 <li>
  <p>For each <var>node</var> in <var>nodes</var>, and then <a for=list>for each</a>
  <var>registered</var> of <var>node</var>'s <a>registered observer list</a>:

  <ol>
   <li><p>Let <var>options</var> be <var>registered</var>'s
   <a for="registered observer">options</a>.

   <li>
    <p>If none of the following are true

    <ul class=brief>
     <li><var>node</var> is not <var>target</var> and <var>options</var>'s
     {{MutationObserverInit/subtree}} is false

     <li><var>type</var> is "<code>attributes</code>" and <var>options</var>'s
     {{MutationObserverInit/attributes}} is not true
     <!--not true==false||omitted-->

     <li><var>type</var> is "<code>attributes</code>", <var>options</var>'s
     {{MutationObserverInit/attributeFilter}} is present, and <var>options</var>'s
     {{MutationObserverInit/attributeFilter}} does not contain <var>name</var> or
     <var>namespace</var> is non-null

     <li><var>type</var> is "<code>characterData</code>" and <var>options</var>'s
     {{MutationObserverInit/characterData}} is not true
     <!--not true==false||omitted-->

     <li><var>type</var> is "<code>childList</code>" and <var>options</var>'s
     {{MutationObserverInit/childList}} is false
    </ul>

    <p>then:

    <ol>
     <li><p>Let <var>mo</var> be <var>registered</var>'s <a for="registered observer">observer</a>.

     <li><p>If <var>interestedObservers</var>[<var>mo</var>] does not <a for=map>exist</a>, then
     <a for=map>set</a> <var>interestedObservers</var>[<var>mo</var>] to null.

     <li><p>If either <var>type</var> is "<code>attributes</code>" and <var>options</var>'s
     {{MutationObserverInit/attributeOldValue}} is true, or <var>type</var> is
     "<code>characterData</code>" and <var>options</var>'s
     {{MutationObserverInit/characterDataOldValue}} is true, then <a for=map>set</a>
     <var>interestedObservers</var>[<var>mo</var>] to <var>oldValue</var>.
    </ol>
  </ol>

 <li>
  <p><a for=map>For each</a> <var>observer</var> → <var>mappedOldValue</var> of
  <var>interestedObservers</var>:

  <ol>
   <li><p>Let <var>record</var> be a new {{MutationRecord}} object with its {{MutationRecord/type}}
   set to <var>type</var>, {{MutationRecord/target}} set to <var>target</var>,
   {{MutationRecord/attributeName}} set to <var>name</var>, {{MutationRecord/attributeNamespace}}
   set to <var>namespace</var>, {{MutationRecord/oldValue}} set to <var>mappedOldValue</var>,
   {{MutationRecord/addedNodes}} set to <var>addedNodes</var>,
   {{MutationRecord/removedNodes}} set to <var>removedNodes</var>,
   {{MutationRecord/previousSibling}} set to <var>previousSibling</var>, and
   {{MutationRecord/nextSibling}} set to <var>nextSibling</var>.

   <li><p><a for=queue>Enqueue</a> <var>record</var> to <var>observer</var>'s
   <a for=MutationObserver>record queue</a>.
  </ol>

 <li><p><a>Queue a mutation observer microtask</a>.
</ol>

<p>To <dfn noexport>queue a tree mutation record</dfn> for <var>target</var> with
<var>addedNodes</var>, <var>removedNodes</var>, <var>previousSibling</var>, and
<var>nextSibling</var>, <a>queue a mutation record</a> of "<code>childList</code>" for
<var>target</var> with null, null, null, <var>addedNodes</var>, <var>removedNodes</var>,
<var>previousSibling</var>, and <var>nextSibling</var>.


<h4 id=interface-mutationrecord>Interface {{MutationRecord}}</h4>

<pre class=idl>
[Exposed=Window]
interface MutationRecord {
  readonly attribute DOMString type;
  [SameObject] readonly attribute Node target;
  [SameObject] readonly attribute NodeList addedNodes;
  [SameObject] readonly attribute NodeList removedNodes;
  readonly attribute Node? previousSibling;
  readonly attribute Node? nextSibling;
  readonly attribute DOMString? attributeName;
  readonly attribute DOMString? attributeNamespace;
  readonly attribute DOMString? oldValue;
};
</pre>

<dl class=domintro>
 <dt><code><var>record</var> . {{MutationRecord/type}}</code>
 <dd>Returns "<code>attributes</code>" if it was an
 <a>attribute</a> mutation.
 "<code>characterData</code>" if it was a mutation to a
 {{CharacterData}} <a>node</a>. And
 "<code>childList</code>" if it was a mutation to the
 <a>tree</a> of
 <a for=/>nodes</a>.

 <dt><code><var>record</var> . {{MutationRecord/target}}</code>
 <dd>Returns the <a>node</a> the mutation
 affected, depending on the {{MutationRecord/type}}.
 For "<code>attributes</code>", it is the
 <a for="/">element</a> whose
 <a>attribute</a> changed. For
 "<code>characterData</code>", it is the {{CharacterData}}
 <a>node</a>. For "<code>childList</code>",
 it is the  <a>node</a> whose
 <a>children</a> changed.

 <dt><code><var>record</var> . {{MutationRecord/addedNodes}}</code>
 <dt><code><var>record</var> . {{MutationRecord/removedNodes}}</code>
 <dd>Return the <a for=/>nodes</a> added and removed
 respectively.

 <dt><code><var>record</var> . {{MutationRecord/previousSibling}}</code>
 <dt><code><var>record</var> . {{MutationRecord/nextSibling}}</code>
 <dd>Return the <a lt="previous sibling">previous</a> and <a for=tree>next sibling</a> respectively
 of the added or removed <a for=/>nodes</a>, and null otherwise.

 <dt><code><var>record</var> . {{MutationRecord/attributeName}}</code>
 <dd>Returns the
 <a for=Attr>local name</a> of the
 changed <a>attribute</a>, and null otherwise.

 <dt><code><var>record</var> . {{MutationRecord/attributeNamespace}}</code>
 <dd>Returns the <a for=Attr>namespace</a> of the
 changed <a>attribute</a>, and null otherwise.

 <dt><code><var>record</var> . {{MutationRecord/oldValue}}</code>
 <dd>The return value depends on
 {{MutationRecord/type}}. For
 "<code>attributes</code>", it is the
 <a for=Attr>value</a> of the
 changed <a>attribute</a> before the change.
 For "<code>characterData</code>", it is the
 <a for=CharacterData>data</a> of the changed
 <a>node</a> before the change. For
 "<code>childList</code>", it is null.
</dl>

<p>The <dfn attribute for=MutationRecord>type</dfn>, <dfn attribute for=MutationRecord>target</dfn>,
<dfn attribute for="MutationRecord">addedNodes</dfn>,
<dfn attribute for="MutationRecord">removedNodes</dfn>,
<dfn attribute for="MutationRecord">previousSibling</dfn>,
<dfn attribute for="MutationRecord">nextSibling</dfn>,
<dfn attribute for="MutationRecord">attributeName</dfn>,
<dfn attribute for="MutationRecord">attributeNamespace</dfn>, and
<dfn attribute for="MutationRecord">oldValue</dfn> attributes must return the values they were
initialized to.


<h4 id=garbage-collection>Garbage collection</h4>

<p><a for=/>Nodes</a> have a strong reference to <a>registered observers</a> in their
<a>registered observer list</a>.

<p><a>Registered observers</a> in a <a for=/>node</a>'s <a>registered observer list</a> have a weak
reference to the <a for=/>node</a>.


<h3 id=interface-node>Interface {{Node}}</h3>

<pre class=idl>
[Exposed=Window]
interface Node : EventTarget {
  const unsigned short ELEMENT_NODE = 1;
  const unsigned short ATTRIBUTE_NODE = 2;
  const unsigned short TEXT_NODE = 3;
  const unsigned short CDATA_SECTION_NODE = 4;
  const unsigned short ENTITY_REFERENCE_NODE = 5; // historical
  const unsigned short ENTITY_NODE = 6; // historical
  const unsigned short PROCESSING_INSTRUCTION_NODE = 7;
  const unsigned short COMMENT_NODE = 8;
  const unsigned short DOCUMENT_NODE = 9;
  const unsigned short DOCUMENT_TYPE_NODE = 10;
  const unsigned short DOCUMENT_FRAGMENT_NODE = 11;
  const unsigned short NOTATION_NODE = 12; // historical
  readonly attribute unsigned short nodeType;
  readonly attribute DOMString nodeName;

  readonly attribute USVString baseURI;

  readonly attribute boolean isConnected;
  readonly attribute Document? ownerDocument;
  Node getRootNode(optional GetRootNodeOptions options = {});
  readonly attribute Node? parentNode;
  readonly attribute Element? parentElement;
  boolean hasChildNodes();
  [SameObject] readonly attribute NodeList childNodes;
  readonly attribute Node? firstChild;
  readonly attribute Node? lastChild;
  readonly attribute Node? previousSibling;
  readonly attribute Node? nextSibling;

  [CEReactions] attribute DOMString? nodeValue;
  [CEReactions] attribute DOMString? textContent;
  [CEReactions] void normalize();

  [CEReactions, NewObject] Node cloneNode(optional boolean deep = false);
  boolean isEqualNode(Node? otherNode);
  boolean isSameNode(Node? otherNode); // historical alias of ===

  const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01;
  const unsigned short DOCUMENT_POSITION_PRECEDING = 0x02;
  const unsigned short DOCUMENT_POSITION_FOLLOWING = 0x04;
  const unsigned short DOCUMENT_POSITION_CONTAINS = 0x08;
  const unsigned short DOCUMENT_POSITION_CONTAINED_BY = 0x10;
  const unsigned short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
  unsigned short compareDocumentPosition(Node other);
  boolean contains(Node? other);

  DOMString? lookupPrefix(DOMString? namespace);
  DOMString? lookupNamespaceURI(DOMString? prefix);
  boolean isDefaultNamespace(DOMString? namespace);

  [CEReactions] Node insertBefore(Node node, Node? child);
  [CEReactions] Node appendChild(Node node);
  [CEReactions] Node replaceChild(Node node, Node child);
  [CEReactions] Node removeChild(Node child);
};

dictionary GetRootNodeOptions {
  boolean composed = false;
};
</pre>

<p class="note no-backref">{{Node}} is an abstract interface and does not exist as <a>node</a>. It
is used by all <a for=/>nodes</a> ({{Document}}, {{DocumentType}}, {{DocumentFragment}}, {{Element}},
{{Text}}, {{ProcessingInstruction}}, and {{Comment}}).

<p>Each <a>node</a> has an associated
<dfn export for=Node id=concept-node-document>node document</dfn>, set upon creation, that is a
<a>document</a>.

<p class="note no-backref">A <a>node</a>'s <a for=Node>node document</a> can be changed by the
<a>adopt</a> algorithm.

<p>A <a>node</a>'s <a>get the parent</a> algorithm, given an <var>event</var>, returns the
<a>node</a>'s <a>assigned slot</a>, if <a>node</a> is <a>assigned</a>, and <a>node</a>'s
<a for=tree>parent</a> otherwise.

<p class="note no-backref">Each <a for=/>node</a> also has a <a>registered observer list</a>.

<hr>

<dl class=domintro>
 <dt><code><var>node</var> . {{Node/nodeType}}</code>
 <dd>
  Returns the type of <var>node</var>, represented by a number from the following list:

  <dl>
   <dt><code>{{Node}} . {{Node/ELEMENT_NODE}}</code> (1)
   <dd><var>node</var> is an
   <a for="/">element</a>.

   <dt><code>{{Node}} . {{Node/TEXT_NODE}}</code> (3)
   <dd><var>node</var> is a {{Text}}
   <a>node</a>.

   <dt><code>{{Node}} . {{Node/CDATA_SECTION_NODE}}</code> (4)
   <dd><var>node</var> is a {{CDATASection}} <a>node</a>.

   <dt><code>{{Node}} . {{Node/PROCESSING_INSTRUCTION_NODE}}</code> (7)
   <dd><var>node</var> is a {{ProcessingInstruction}}
   <a>node</a>.

   <dt><code>{{Node}} . {{Node/COMMENT_NODE}}</code> (8)
   <dd><var>node</var> is a {{Comment}}
   <a>node</a>.

   <dt><code>{{Node}} . {{Node/DOCUMENT_NODE}}</code> (9)
   <dd><var>node</var> is a
   <a>document</a>.

   <dt><code>{{Node}} . {{Node/DOCUMENT_TYPE_NODE}}</code> (10)
   <dd><var>node</var> is a
   <a>doctype</a>.

   <dt><code>{{Node}} . {{Node/DOCUMENT_FRAGMENT_NODE}}</code> (11)
   <dd><var>node</var> is a {{DocumentFragment}} <a>node</a>.
  </dl>

 <dt><code><var>node</var> . {{Node/nodeName}}</code>
 <dd>
  Returns a string appropriate for the type of <var>node</var>, as
  follows:

  <dl>
   <dt>{{Element}}
   <dd>Its <a for=Element>HTML-uppercased qualified name</a>.

   <dt>{{Attr}}
   <dd>Its <a for=Attr>qualified name</a>.

   <dt>{{Text}}
   <dd>"<code>#text</code>".

   <dt>{{CDATASection}}
   <dd>"<code>#cdata-section</code>".

   <dt>{{ProcessingInstruction}}
   <dd>Its <a for=ProcessingInstruction>target</a>.

   <dt>{{Comment}}
   <dd>"<code>#comment</code>".

   <dt>{{Document}}
   <dd>"<code>#document</code>".

   <dt>{{DocumentType}}
   <dd>Its <a for=DocumentType>name</a>.

   <dt>{{DocumentFragment}}
   <dd>"<code>#document-fragment</code>".
  </dl>
</dl>

The <dfn attribute for=Node>nodeType</dfn> attribute's getter, when invoked, must return
the first matching statement, switching on the <a>context object</a>:

<dl class=switch>
 <dt>{{Element}}
 <dd><dfn const for=Node>ELEMENT_NODE</dfn> (1)

 <dt>{{Attr}}
 <dd><dfn const for=Node>ATTRIBUTE_NODE</dfn> (2);

 <dt>{{Text}}
 <dd><dfn const for=Node>TEXT_NODE</dfn> (3);

 <dt>{{CDATASection}}
 <dd><dfn const for=Node>CDATA_SECTION_NODE</dfn> (4);

 <dt>{{ProcessingInstruction}}
 <dd><dfn const for=Node>PROCESSING_INSTRUCTION_NODE</dfn> (7);

 <dt>{{Comment}}
 <dd><dfn const for=Node>COMMENT_NODE</dfn> (8);

 <dt>{{Document}}
 <dd><dfn const for=Node>DOCUMENT_NODE</dfn> (9);

 <dt>{{DocumentType}}
 <dd><dfn const for=Node>DOCUMENT_TYPE_NODE</dfn> (10);

 <dt>{{DocumentFragment}}
 <dd><dfn const for=Node>DOCUMENT_FRAGMENT_NODE</dfn> (11).
</dl>

<!-- NodeExodus
<hr>

The <dfn attribute for=Node>namespaceURI</dfn> attribute must return the namespace that is associated with the node, if there is one and it's not the empty string, and null otherwise.

The <dfn attribute for=Node>prefix</dfn> attribute must return the prefix that is associated with the node, if there is one and it's not the empty string, and null otherwise.
<!- - support setting? - - On setting, it must run these steps:

<ol>
 <li>Let <var>prefix</var> be the value being assigned.
 <li>
  If <var>prefix</var> is not null, run these substeps:
  <ol>
   <li>If <var>prefix</var> does not match the
   <code><a type>Name</a></code> production in XML,
   <a>throw</a> an
   "{{InvalidCharacterError!!exception}}" {{DOMException}}.
   <li>If <var>prefix</var> does not match the <a type>NCName</a> production in Namespaces in XML, <a>throw</a> a
   "{{NamespaceError!!exception}}" {{DOMException}}.
  </ol>
 <li>Actually this does not match any browser. Let's try to drop it instead.
</ol>- ->

The <dfn attribute for=Node>localName</dfn> attribute
must return the local name that is associated with the node, if it has one,
and null otherwise.-->

<p>The <dfn attribute for=Node>nodeName</dfn> attribute's getter, when invoked, must return the
first matching statement, switching on the <a>context object</a>:

<dl class=switch>
 <dt>{{Element}}
 <dd>Its <a for=Element>HTML-uppercased qualified name</a>.

 <dt>{{Attr}}
 <dd>Its <a for=Attr>qualified name</a>.

 <dt>{{Text}}
 <dd>"<code>#text</code>".

 <dt>{{CDATASection}}
 <dd>"<code>#cdata-section</code>".

 <dt>{{ProcessingInstruction}}
 <dd>Its <a for=ProcessingInstruction>target</a>.

 <dt>{{Comment}}
 <dd>"<code>#comment</code>".

 <dt>{{Document}}
 <dd>"<code>#document</code>".

 <dt>{{DocumentType}}
 <dd>Its <a for=DocumentType>name</a>.

 <dt>{{DocumentFragment}}
 <dd>"<code>#document-fragment</code>".
</dl>

<hr>

<dl class=domintro>
 <dt><code><var>node</var> . {{Node/baseURI}}</code>
 <dd>Returns <var>node</var>'s <a for=Node>node document</a>'s <a>document base URL</a>.
</dl>

The <dfn attribute for=Node><code>baseURI</code></dfn> attribute's getter must return
<a for=Node>node document</a>'s <a>document base URL</a>, <a lt="URL serializer" spec=url>serialized</a>.

<hr>

<dl class=domintro>
 <dt><code><var>node</var> . {{Node/isConnected}}</code>
 <dd><p>Returns true if <var>node</var> is <a>connected</a> and false otherwise.

 <dt><code><var>node</var> . {{Node/ownerDocument}}</code>
 <dd>
  Returns the <a for=Node>node document</a>.
  Returns null for <a>documents</a>.

 <dt><code><var>node</var> . {{Node/getRootNode()}}</code>
 <dd>Returns <var>node</var>'s <a for=tree>root</a>.

 <dt><code><var>node</var> . <a idl lt=getRootNode()>getRootNode</a>({ composed:true })</code>
 <dd>Returns <var>node</var>'s <a>shadow-including root</a>.

 <dt><code><var>node</var> . {{Node/parentNode}}</code>
 <dd>Returns the <a for=tree>parent</a>.

 <dt><code><var>node</var> . {{Node/parentElement}}</code>
 <dd>Returns the <a>parent element</a>.

 <dt><code><var>node</var> . {{Node/hasChildNodes()}}</code>
 <dd>Returns whether <var>node</var> has
 <a>children</a>.

 <dt><code><var>node</var> . {{Node/childNodes}}</code>
 <dd>Returns the <a>children</a>.

 <dt><code><var>node</var> . {{Node/firstChild}}</code>
 <dd>Returns the <a for=tree>first child</a>.

 <dt><code><var>node</var> . {{Node/lastChild}}</code>
 <dd>Returns the <a>last child</a>.

 <dt><code><var>node</var> . {{Node/previousSibling}}</code>
 <dd>Returns the
 <a>previous sibling</a>.

 <dt><code><var>node</var> . {{Node/nextSibling}}</code>
 <dd>Returns the
 <a for=tree>next sibling</a>.
</dl>

<p>The <dfn attribute for=Node><code>isConnected</code></dfn> attribute's getter must return true,
if <a>context object</a> is <a>connected</a>, and false otherwise.</p>

<p>The <dfn attribute for=Node><code>ownerDocument</code></dfn> attribute's getter must return null,
if the <a>context object</a> is a <a>document</a>, and the <a>context object</a>'s
<a for=Node>node document</a> otherwise.

<p class="note">The <a for=Node>node document</a> of a <a>document</a> is that <a>document</a> itself. All
<a for=/>nodes</a> have a <a for=Node>node document</a> at all times.

<p>The <dfn method for=Node><code>getRootNode(<var>options</var>)</code></dfn> method, when invoked,
must return <a>context object</a>'s <a>shadow-including root</a> if <var>options</var>'s
{{GetRootNodeOptions/composed}} is true, and <a>context object</a>'s <a for=tree>root</a> otherwise.

<p>The <dfn attribute for=Node><code>parentNode</code></dfn> attribute's getter must return the
<a>context object</a>'s <a for=tree>parent</a>.

<p class="note">An {{Attr}} <a>node</a> has no <a for=tree>parent</a>.

<p>The <dfn attribute for=Node><code>parentElement</code></dfn> attribute's getter must return the
<a>context object</a>'s <a>parent element</a>.

<p>The <dfn method for=Node><code>hasChildNodes()</code></dfn> method, when invoked, must return
true if the <a>context object</a> has <a>children</a>, and false otherwise.

<p>The <dfn attribute for=Node><code>childNodes</code></dfn> attribute's getter must return a
{{NodeList}} rooted at the <a>context object</a> matching only <a>children</a>.

<p>The <dfn attribute for=Node><code>firstChild</code> </dfn> attribute's getter must return the
<a>context object</a>'s <a for=tree>first child</a>.

<p>The <dfn attribute for=Node><code>lastChild</code></dfn> attribute's getter must return the
<a>context object</a>'s <a>last child</a>.

<p>The <dfn attribute for=Node><code>previousSibling</code></dfn> attribute's getter must return the
<a>context object</a>'s <a>previous sibling</a>.

<p class="note">An {{Attr}} <a>node</a> has no <a for=tree>siblings</a>.

<p>The <dfn attribute for=Node><code>nextSibling</code></dfn> attribute's getter must return the
<a>context object</a>'s <a for=tree>next sibling</a>.

<hr>

<!-- TODO: domintro -->

The <dfn attribute for=Node>nodeValue</dfn> attribute
must return the following, depending on the <a>context object</a>:

<dl class=switch>
 <dt>{{Attr}}
 <dd><a>Context object</a>'s <a for=Attr>value</a>.

 <dt>{{Text}}
 <dt>{{ProcessingInstruction}}
 <dt>{{Comment}}
 <dd><a>Context object</a>'s <a for=CharacterData>data</a>.

 <dt>Any other node
 <dd>Null.
</dl>

The {{Node/nodeValue}} attribute must,
on setting, if the new value is null, act as if it was the empty string
instead, and then do as described below, depending on the <a>context object</a>:

<dl class=switch>
 <dt>{{Attr}}
 <dd><p><a>Set an existing attribute value</a> with <a>context object</a> and new value.

 <dt>{{Text}}
 <dt>{{ProcessingInstruction}}
 <dt>{{Comment}}
 <dd><p><a>Replace data</a> with node <a>context object</a>, offset 0, count <a>context object</a>'s
 <a for=Node>length</a>, and data new value.

 <dt>Any other node
 <dd><p>Do nothing.
</dl>

<p>The <dfn attribute for=Node><code>textContent</code></dfn> attribute's getter must return the
following, switching on <a>context object</a>:

<dl class=switch>
 <dt>{{DocumentFragment}}
 <dt>{{Element}}
 <dd>The <a>descendant text content</a> of the <a>context object</a>.

 <dt>{{Attr}}
 <dd><a>Context object</a>'s <a for=Attr>value</a>.

 <dt>{{Text}}
 <dt>{{ProcessingInstruction}}
 <dt>{{Comment}}
 <dd><a>Context object</a>'s <a for=CharacterData>data</a>.

 <dt>Any other node
 <dd>Null.
</dl>

<p>To <dfn export>string replace all</dfn> with a string <var>string</var> within a
<a for=/>node</a> <var>parent</var>, run these steps:

<ol>
 <li><p>Let <var>node</var> be null.

 <li><p>If <var>string</var> is not the empty string, then set <var>node</var> to a new {{Text}}
 <a for=/>node</a> whose <a for=CharacterData>data</a> is <var>string</var> and
 <a for=Node>node document</a> is <var>parent</var>'s <a for=Node>node document</a>.

 <li><p><a for=Node>Replace all</a> with <var>node</var> within <var>parent</var>.
</ol>

<p>The {{Node/textContent}} attribute's setter must, if the given value is null, act as if it was
the empty string instead, and then do as described below, switching on <a>context object</a>:

<dl class=switch>
 <dt>{{DocumentFragment}}
 <dt>{{Element}}
 <dd><p><a>String replace all</a> with the given value within the <a>context object</a>.

 <dt>{{Attr}}
 <dd><p><a>Set an existing attribute value</a> with <a>context object</a> and new value.

 <dt>{{Text}}
 <dt>{{ProcessingInstruction}}
 <dt>{{Comment}}
 <dd><p><a>Replace data</a> with node <a>context object</a>, offset 0, count <a>context object</a>'s
 <a for=Node>length</a>, and data the given value.

 <dt>Any other node
 <dd><p>Do nothing.
</dl>

<hr>

<dl class=domintro>
 <dt><code><var>node</var> . {{Node/normalize()}}</code>
 <dd>Removes <a for=Node>empty</a> <a>exclusive <code>Text</code> nodes</a> and concatenates the
 <a for=CharacterData>data</a> of remaining <a>contiguous exclusive <code>Text</code> nodes</a>
 into the first of their <a for=/>nodes</a>.
</dl>

<p>The <dfn method for=Node><code>normalize()</code></dfn> method, when invoked, must run these
steps for each <a>descendant</a> <a>exclusive <code>Text</code> node</a> <var>node</var> of
<a>context object</a>:

<ol>
 <li>Let <var>length</var> be <var>node</var>'s <a for=Node>length</a>.

 <li>If <var>length</var> is zero, then <a for=/>remove</a> <var>node</var> and continue with the
 next <a>exclusive <code>Text</code> node</a>, if any.

 <li>Let <var>data</var> be the <a for=string>concatenation</a> of the <a for=CharacterData>data</a>
 of <var>node</var>'s <a>contiguous exclusive <code>Text</code> nodes</a> (excluding itself), in
 <a>tree order</a>.

 <li><a>Replace data</a> with node <var>node</var>, offset <var>length</var>, count 0, and data
 <var>data</var>.

 <li>Let <var>currentNode</var> be <var>node</var>'s <a for=tree>next sibling</a>.

 <li>
  <p>While <var>currentNode</var> is an <a>exclusive <code>Text</code> node</a>:

  <ol>
   <li><p>For each <a>live range</a> whose <a for=range>start node</a> is <var>currentNode</var>,
   add <var>length</var> to its <a for=range>start offset</a> and set its
   <a for=range>start node</a> to <var>node</var>.

   <li><p>For each <a>live range</a> whose <a for=range>end node</a> is <var>currentNode</var>, add
   <var>length</var> to its <a for=range>end offset</a> and set its <a for=range>end node</a> to
   <var>node</var>.

   <li><p>For each <a>live range</a> whose <a for=range>start node</a> is <var>currentNode</var>'s
   <a for=tree>parent</a> and <a for=range>start offset</a> is <var>currentNode</var>'s
   <a for=tree>index</a>, set its <a for=range>start node</a> to <var>node</var> and its
   <a for=range>start offset</a> to <var>length</var>.

   <li><p>For each <a>live range</a> whose <a for=range>end node</a> is <var>currentNode</var>'s
   <a for=tree>parent</a> and <a for=range>end offset</a> is <var>currentNode</var>'s
   <a for=tree>index</a>, set its <a for=range>end node</a> to <var>node</var> and its
   <a for=range>end offset</a> to <var>length</var>.

   <li><p>Add <var>currentNode</var>'s <a for=Node>length</a> to <var>length</var>.

   <li><p>Set <var>currentNode</var> to its <a for=tree>next sibling</a>.
  </ol>

 <li><a for=/>Remove</a> <var>node</var>'s <a>contiguous exclusive <code>Text</code> nodes</a>
 (excluding itself), in <a>tree order</a>.
</ol>

<hr>

<dl class=domintro>
 <dt><code><var>node</var> . <a method for=Node lt=cloneNode()>cloneNode([<var>deep</var> = false])</a></code>
 <dd>Returns a copy of <var>node</var>. If
 <var>deep</var> is true, the copy also includes the
 <var>node</var>'s <a>descendants</a>.

 <dt><code><var>node</var> . {{Node/isEqualNode(otherNode)}}</code>
 <dd>Returns whether <var>node</var> and <var>otherNode</var>
 have the same properties.
</dl>

<div class=impl>

<a lt="Other applicable specifications">Specifications</a> may define
<dfn export id=concept-node-clone-ext>cloning steps</dfn> for all or some <a for=/>nodes</a>. The
algorithm is passed <var>copy</var>, <var>node</var>, <var>document</var>, and an optional
<i>clone children flag</i>, as indicated in the <a lt="clone a node">clone</a> algorithm.

<p class="note no-backref">HTML defines <a>cloning steps</a> for <{script}> and <{input}>
elements. SVG ought to do the same for its <{script}> elements, but does not call this out
at the moment.

<p>To <dfn export id=concept-node-clone lt="clone a node" local-lt="clone">clone</dfn> a
<var>node</var>, with an optional <var>document</var> and <i>clone children flag</i>, run these
steps:
<!-- This algorithm is used by dom-Node-cloneNode, dom-Document-importNode,
dom-Range-extractContents, dom-Range-cloneContents -->

<ol>
 <li><p>If <var>document</var> is not given, let <var>document</var> be <var>node</var>'s
 <a for=Node>node document</a>.

 <li>
  <p>If <var>node</var> is an <a for=/>element</a>, then:

  <ol>
   <li><p>Let <var>copy</var> be the result of <a>creating an element</a>, given
   <var>document</var>, <var>node</var>'s <a for=Element>local name</a>, <var>node</var>'s
   <a for=Element>namespace</a>, <var>node</var>'s <a for=Element>namespace prefix</a>, and
   <var>node</var>'s <a><code>is</code> value</a>, with the <var>synchronous custom elements
   flag</var> unset.

   <li>
    <p><a for=list>For each</a> <var>attribute</var> in <var>node</var>'s
    <a for=Element>attribute list</a>:

    <ol>
     <li><p>Let <var>copyAttribute</var> be a <a>clone</a> of <var>attribute</var>.

     <li><p><a lt="append an attribute">Append</a> <var>copyAttribute</var> to <var>copy</var>.
    </ol>
   </li>
  </ol>
 </li>

 <li>
  <p>Otherwise, let <var>copy</var> be a <a>node</a> that implements the same interfaces as
  <var>node</var>, and fulfills these additional requirements, switching on
  <var>node</var>:

  <dl class=switch>
   <dt>{{Document}}
   <dd><p>Set <var>copy</var>'s <a for=Document>encoding</a>, <a for=Document>content type</a>,
   <a for=Document>URL</a>, <a for=Document>origin</a>, <a for=Document>type</a>, and
   <a for=Document>mode</a>, to those of <var>node</var>.

   <dt>{{DocumentType}}
   <dd><p>Set <var>copy</var>'s <a for=DocumentType>name</a>, <a>public ID</a>, and
   <a>system ID</a>, to those of <var>node</var>.

   <dt>{{Attr}}
   <dd><p>Set <var>copy</var>'s <a for=Attr>namespace</a>, <a for=Attr>namespace prefix</a>,
   <a for=Attr>local name</a>, and <a for=Attr>value</a>, to those of <var>node</var>.

   <dt>{{Text}}
   <dt>{{Comment}}
   <dd>Set <var>copy</var>'s <a for=CharacterData>data</a>, to that of <var>node</var>.

   <dt>{{ProcessingInstruction}}
   <dd>Set <var>copy</var>'s <a for=ProcessingInstruction>target</a> and
   <a for=CharacterData>data</a> to those of <var>node</var>.

   <dt>Any other node
   <dd>&mdash;
  </dl>

 <li><p>Set <var>copy</var>'s <a for=Node>node document</a> and <var>document</var> to
 <var>copy</var>, if <var>copy</var> is a <a>document</a>, and set <var>copy</var>'s
 <a for=Node>node document</a> to <var>document</var> otherwise.

 <li>Run any <a>cloning steps</a> defined for <var>node</var> in
 <a>other applicable specifications</a> and pass <var>copy</var>, <var>node</var>,
 <var>document</var> and the <i>clone children flag</i> if set, as parameters.

 <li>If the <i>clone children flag</i> is set, <a lt="clone a node">clone</a> all the
 <a>children</a> of <var>node</var> and append them to <var>copy</var>, with
 <var>document</var> as specified and the <i>clone children flag</i> being set.

 <li>Return <var>copy</var>.
</ol>

<p>The <dfn method for=Node><code>cloneNode(<var>deep</var>)</code></dfn> method, when
invoked, must run these steps:

<ol>
 <li><p>If <a>context object</a> is a <a for=/>shadow root</a>, then <a>throw</a> a
 "{{NotSupportedError!!exception}}" {{DOMException}}.

 <li><p>Return a <a lt="clone a node">clone</a> of the <a>context object</a>, with the
 <i>clone children flag</i> set if <var>deep</var> is true.
</ol>

A <a>node</a> <var>A</var>
<dfn export for=Node id=concept-node-equals>equals</dfn> a <a>node</a>
<var>B</var> if all of the following conditions are true:

<ul>
 <li><var>A</var> and <var>B</var>'s
 {{Node/nodeType}} attribute value is identical.
 <li>
  The following are also equal, depending on <var>A</var>:
  <dl class=switch>
   <dt>{{DocumentType}}
   <dd>Its <a for=DocumentType>name</a>,
   <a>public ID</a>, and
   <a>system ID</a>.

   <dt>{{Element}}
   <dd>Its <a for=Element>namespace</a>, <a for=Element>namespace prefix</a>,
   <a for=Element>local name</a>, and its <a for=Element>attribute list</a>'s <a for=list>size</a>.

   <dt>{{Attr}}
   <dd>Its <a for=Attr>namespace</a>, <a for=Attr>local name</a>, and <a for=Attr>value</a>.

   <dt>{{ProcessingInstruction}}
   <dd>Its <a for=ProcessingInstruction>target</a> and
   <a for=CharacterData>data</a>.

   <dt>{{Text}}
   <dt>{{Comment}}
   <dd>Its <a for=CharacterData>data</a>.

   <dt>Any other node
   <dd>&mdash;
  </dl>
 <li>If <var>A</var> is an <a for="/">element</a>, each <a>attribute</a> in its
 <a for=Element>attribute list</a> has an <a>attribute</a> that <a for=Node>equals</a> an
 <a>attribute</a> in <var>B</var>'s <a for=Element>attribute list</a>.
 <li><var>A</var> and <var>B</var> have the same number of
 <a>children</a>.
 <li>Each <a for=tree>child</a> of <var>A</var>
 <a for=Node>equals</a> the
 <a for=tree>child</a> of <var>B</var> at the identical
 <a for=tree>index</a>.
</ul>

<p>The <dfn method for=Node><code>isEqualNode(<var>otherNode</var>)</code></dfn> method, when
invoked, must return true if <var>otherNode</var> is non-null and <a>context object</a>
<a for=Node>equals</a> <var>otherNode</var>, and false otherwise.

<p>The <dfn method for=Node><code>isSameNode(<var>otherNode</var>)</code></dfn> method, when
invoked, must return true if <var>otherNode</var> is <a>context object</a>, and false otherwise.

</div>

<hr>

<dl class=domintro>
 <dt><code><var>node</var> . {{compareDocumentPosition(other)}}</code>
 <dd>
  Returns a bitmask indicating the position of <var>other</var>
  relative to <var>node</var>. These are the bits that can be set:

  <dl>
   <dt><code>{{Node}} . {{Node/DOCUMENT_POSITION_DISCONNECTED}}</code> (1)
   <dd>Set when <var>node</var> and <var>other</var> are not in the
   same <a>tree</a>.

   <dt><code>{{Node}} . {{Node/DOCUMENT_POSITION_PRECEDING}}</code> (2)
   <dd>Set when <var>other</var> is
   <a>preceding</a>
   <var>node</var>.

   <dt><code>{{Node}} . {{Node/DOCUMENT_POSITION_FOLLOWING}}</code> (4)
   <dd>Set when <var>other</var> is
   <a>following</a>
   <var>node</var>.

   <dt><code>{{Node}} . {{Node/DOCUMENT_POSITION_CONTAINS}}</code> (8)
   <dd>Set when <var>other</var> is an
   <a>ancestor</a> of
   <var>node</var>.

   <dt><code>{{Node}} . {{Node/DOCUMENT_POSITION_CONTAINED_BY}}</code> (16, 10 in hexadecimal)
   <dd>Set when <var>other</var> is a
   <a>descendant</a> of
   <var>node</var>.
  </dl>

 <dt><code><var>node</var> . {{Node/contains(other)}}</code>
 <dd>Returns true if <var>other</var> is an
 <a>inclusive descendant</a>
 of <var>node</var>, and false otherwise.
</dl>

These are the constants
{{compareDocumentPosition()}}
returns as mask:

<ul class="brief">
 <li><dfn const for=Node>DOCUMENT_POSITION_DISCONNECTED</dfn> (1);
 <li><dfn const for=Node>DOCUMENT_POSITION_PRECEDING</dfn> (2);
 <li><dfn const for=Node>DOCUMENT_POSITION_FOLLOWING</dfn> (4);
 <li><dfn const for=Node>DOCUMENT_POSITION_CONTAINS</dfn> (8);
 <li><dfn const for=Node>DOCUMENT_POSITION_CONTAINED_BY</dfn> (16, 10 in hexadecimal);
 <li><dfn const for=Node>DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC</dfn> (32, 20 in hexadecimal).
</ul>

<p>The <dfn method for=Node><code>compareDocumentPosition(<var>other</var>)</code></dfn> method,
when invoked, must run these steps:

<ol>
 <li><p>If <a>context object</a> is <var>other</var>, then return zero.

 <li><p>Let <var>node1</var> be <var>other</var> and <var>node2</var> be <a>context object</a>.

 <li><p>Let <var>attr1</var> and <var>attr2</var> be null.

 <li><p>If <var>node1</var> is an <a>attribute</a>, then set <var>attr1</var> to <var>node1</var>
 and <var>node1</var> to <var>attr1</var>'s <a for=Attr>element</a>.

 <li>
  <p>If <var>node2</var> is an <a>attribute</a>, then:

  <ol>
   <li><p>Set <var>attr2</var> to <var>node2</var> and <var>node2</var> to <var>attr2</var>'s
   <a for=Attr>element</a>.

   <li>
    <p>If <var>attr1</var> and <var>node1</var> are non-null, and <var>node2</var> is
    <var>node1</var>, then:

    <ol>
     <li>
      <p><a for=list>For each</a> <var>attr</var> in <var>node2</var>'s
      <a for=Element>attribute list</a>:

      <ol>
       <li><p>If <var>attr</var> <a for=Node>equals</a> <var>attr1</var>, then return the result of
       adding {{Node/DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC}} and
       {{Node/DOCUMENT_POSITION_PRECEDING}}.

       <li><p>If <var>attr</var> <a for=Node>equals</a> <var>attr2</var>, then return the result of
       adding {{Node/DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC}} and
       {{Node/DOCUMENT_POSITION_FOLLOWING}}.
      </ol>
    </ol>
  </ol>

 <li>
  <p>If <var>node1</var> or <var>node2</var> is null, or <var>node1</var>'s <a for=tree>root</a> is
  not <var>node2</var>'s <a for=tree>root</a>, then return the result of adding
  {{Node/DOCUMENT_POSITION_DISCONNECTED}}, {{Node/DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC}}, and
  either {{Node/DOCUMENT_POSITION_PRECEDING}} or {{Node/DOCUMENT_POSITION_FOLLOWING}}, with the
  constraint that this is to be consistent, together.

  <p class="note no-backref">Whether to return {{Node/DOCUMENT_POSITION_PRECEDING}} or
  {{Node/DOCUMENT_POSITION_FOLLOWING}} is typically implemented via pointer comparison. In
  JavaScript implementations a cached <code class='lang-javascript'>Math.random()</code> value can
  be used.

 <li><p>If <var>node1</var> is an <a>ancestor</a> of <var>node2</var> and <var>attr1</var> is null,
 or <var>node1</var> is <var>node2</var> and <var>attr2</var> is non-null, then return the result of
 adding {{Node/DOCUMENT_POSITION_CONTAINS}} to {{Node/DOCUMENT_POSITION_PRECEDING}}.

 <li><p>If <var>node1</var> is a <a>descendant</a> of <var>node2</var> and <var>attr2</var> is null,
 or <var>node1</var> is <var>node2</var> and <var>attr1</var> is non-null, then return the result of
 adding {{Node/DOCUMENT_POSITION_CONTAINED_BY}} to {{Node/DOCUMENT_POSITION_FOLLOWING}}.

 <li>
  <p>If <var>node1</var> is <a>preceding</a> <var>node2</var>, then return
  {{Node/DOCUMENT_POSITION_PRECEDING}}.

  <p class="note">Due to the way <a>attributes</a> are handled in this algorithm this results in a
  <a>node</a>'s <a>attributes</a> counting as <a>preceding</a> that <a>node</a>'s <a>children</a>,
  despite <a>attributes</a> not <a>participating</a> in a <a>tree</a>.

 <li><p>Return {{Node/DOCUMENT_POSITION_FOLLOWING}}.
</ol>

<p>The <dfn method for=Node><code>contains(<var>other</var>)</code></dfn> method, when invoked, must
return true if <var>other</var> is an <a>inclusive descendant</a> of <a>context object</a>, and
false otherwise (including when <var>other</var> is null).

<hr>

<!-- TODO: domintro -->

<!--
 XXX apparently these algorithms might not be quite correct
 https://bugzilla.mozilla.org/show_bug.cgi?id=312019
 https://bugzilla.mozilla.org/show_bug.cgi?id=505178
-->

<p>To
<dfn export lt="locate a namespace prefix|locating a namespace prefix">locate a namespace prefix</dfn>
for an <var>element</var> using <var>namespace</var>, run these steps:

<ol>
 <li><p>If <var>element</var>'s <a for=Element>namespace</a> is <var>namespace</var> and its
 <a for=Element>namespace prefix</a> is non-null, then return its
 <a for=Element>namespace prefix</a>.

 <li><p>If <var>element</var> <a lt="has an attribute">has</a> an <a>attribute</a> whose
 <a for=Attr>namespace prefix</a> is "<code>xmlns</code>" and <a for=Attr>value</a> is
 <var>namespace</var>, then return <var>element</var>'s first such <a>attribute</a>'s
 <a for=Attr>local name</a>.

 <li><p>If <var>element</var>'s <a>parent element</a> is not null, then return the result of running
 <a>locate a namespace prefix</a> on that <a for="/">element</a> using <var>namespace</var>.

 <li><p>Return null.
</ol>

<p>To <dfn export>locate a namespace</dfn> for a <var>node</var> using <var>prefix</var>, switch on
<var>node</var>:

<dl class=switch>
 <dt>{{Element}}
 <dd>
  <ol>
   <li><p>If its <a for=Element>namespace</a> is non-null and its
   <a for=Element>namespace prefix</a> is <var>prefix</var>, then return
   <a for=Element>namespace</a>.

   <li><p>If it <a lt="has an attribute">has</a> an <a>attribute</a> whose <a for=Attr>namespace</a>
   is the <a>XMLNS namespace</a>, <a for=Attr>namespace prefix</a> is "<code>xmlns</code>", and
   <a for=Attr>local name</a> is <var>prefix</var>, or if <var>prefix</var> is null and it
   <a lt="has an attribute">has</a> an <a>attribute</a> whose <a for=Attr>namespace</a> is the
   <a>XMLNS namespace</a>, <a for=Attr>namespace prefix</a> is null, and <a for=Attr>local name</a>
   is "<code>xmlns</code>", then return its <a for=Attr>value</a> if it is not the empty string, and
   null otherwise.

   <li><p>If its <a>parent element</a> is null, then return null.

   <li><p>Return the result of running <a>locate a namespace</a> on its <a>parent element</a> using
   <var>prefix</var>.
  </ol>

 <dt>{{Document}}
 <dd>
  <ol>
   <li><p>If its <a>document element</a> is null, then return null.

   <li><p>Return the result of running <a>locate a namespace</a> on its <a>document element</a>
   using <var>prefix</var>.
  </ol>

 <dt>{{DocumentType}}
 <dt>{{DocumentFragment}}
 <dd><p>Return null.

 <dt>{{Attr}}
 <dd>
  <ol>
   <li><p>If its <a for=Attr>element</a> is null, then return null.

   <li><p>Return the result of running <a>locate a namespace</a> on its <a for=Attr>element</a>
   using <var>prefix</var>.
  </ol>

 <dt>Any other node
 <dd>
  <ol>
   <li><p>If its <a>parent element</a> is null, then return null.

   <li><p>Return the result of running <a>locate a namespace</a> on its <a>parent element</a> using
   <var>prefix</var>.
  </ol>
</dl>

<p>The <dfn method for=Node><code>lookupPrefix(<var>namespace</var>)</code></dfn> method, when
invoked, must run these steps:

<ol>
 <li><p>If <var>namespace</var> is null or the empty string, then return null.

 <li>
  <p>Switch on the <a>context object</a>:

  <dl class=switch>
   <dt>{{Element}}
   <dd><p>Return the result of <a>locating a namespace prefix</a> for it using <var>namespace</var>.

   <dt>{{Document}}
   <dd><p>Return the result of <a>locating a namespace prefix</a> for its <a>document element</a>,
   if its <a>document element</a> is non-null, and null otherwise.

   <dt>{{DocumentType}}
   <dt>{{DocumentFragment}}
   <dd><p>Return null.

   <dt>{{Attr}}
   <dd><p>Return the result of <a>locating a namespace prefix</a> for its <a for=Attr>element</a>,
   if its <a for=Attr>element</a> is non-null, and null otherwise.

   <dt>Any other node
   <dd><p>Return the result of <a>locating a namespace prefix</a> for its <a>parent element</a>, if
   its <a>parent element</a> is non-null, and null otherwise.
  </dl>
</ol>

<p>The <dfn method for=Node><code>lookupNamespaceURI(<var>prefix</var>)</code></dfn> method, when
invoked, must run these steps:

<ol>
 <li><p>If <var>prefix</var> is the empty string, then set it to null.

 <li><p>Return the result of running <a>locate a namespace</a> for the <a>context object</a> using
 <var>prefix</var>.
</ol>

<p>The <dfn method for=Node><code>isDefaultNamespace(<var>namespace</var>)</code></dfn> method, when
invoked, must run these steps:

<ol>
 <li><p>If <var>namespace</var> is the empty string, then set it to null.

 <li><p>Let <var>defaultNamespace</var> be the result of running <a>locate a namespace</a> for
 <a>context object</a> using null.

 <li><p>Return true if <var>defaultNamespace</var> is the same as <var>namespace</var>, and false
 otherwise.
</ol>

<hr>

<p>The <dfn method for=Node><code>insertBefore(<var>node</var>, <var>child</var>)</code></dfn>
method, when invoked, must return the result of <a>pre-inserting</a> <var>node</var> into
<a>context object</a> before <var>child</var>.

<p>The <dfn method for=Node><code>appendChild(<var>node</var>)</code></dfn> method, when invoked,
must return the result of <a>appending</a> <var>node</var> to <a>context object</a>.

<p>The <dfn method for=Node><code>replaceChild(<var>node</var>, <var>child</var>)</code></dfn>
method, when invoked, must return the result of <a>replacing</a> <var>child</var> with
<var>node</var> within <a>context object</a>.

<p>The <dfn method for=Node><code>removeChild(<var>child</var>)</code></dfn> method, when invoked,
must return the result of <a>pre-removing</a> <var>child</var> from <a>context object</a>.

<hr><!-- Collections -->

<p>The
<dfn export id=concept-getelementsbytagname>list of elements with qualified name <var>qualifiedName</var></dfn>
for a <a>node</a> <var>root</var> is the {{HTMLCollection}} returned by the following algorithm:

<ol>
 <li><p>If <var>qualifiedName</var> is "<code>*</code>" (U+002A), return a {{HTMLCollection}} rooted
 at <var>root</var>, whose filter matches only <a>descendant</a> <a for="/">elements</a>.

 <li>
  <p>Otherwise, if <var>root</var>'s <a for=Node>node document</a> is an <a>HTML document</a>,
  return a {{HTMLCollection}} rooted at <var>root</var>, whose filter matches the following
  <a>descendant</a> <a for="/">elements</a>:

  <ul>
   <li><p>Whose <a for=Element>namespace</a> is the <a>HTML namespace</a> and whose
   <a for=Element>qualified name</a> is <var>qualifiedName</var>, in <a>ASCII lowercase</a>.

   <li><p>Whose <a for=Element>namespace</a> is <em>not</em> the <a>HTML namespace</a> and whose
   <a for=Element>qualified name</a> is <var>qualifiedName</var>.
  </ul>

 <li><p>Otherwise, return a {{HTMLCollection}} rooted at <var>root</var>, whose filter matches
 <a>descendant</a> <a for="/">elements</a> whose <a for=Element>qualified name</a> is
 <var>qualifiedName</var>.
</ol>

<p>When invoked with the same argument, and as long as <var>root</var>'s
<a for=Node>node document</a>'s <a for=Document>type</a> has not changed, the same
{{HTMLCollection}} object may be returned as returned by an earlier call.

The
<dfn export id=concept-getelementsbytagnamens>list of elements with namespace
<var>namespace</var> and local name <var>localName</var></dfn>
for a <a>node</a> <var>root</var> is the
{{HTMLCollection}} returned by the following algorithm:

<ol>
 <li>If <var>namespace</var> is the empty string, set it to null.

 <li>If both <var>namespace</var> and <var>localName</var>
 are "<code>*</code>" (U+002A), return a {{HTMLCollection}} rooted at
 <var>root</var>, whose filter matches
 <a>descendant</a>
 <a for="/">elements</a>.

 <li>Otherwise, if <var>namespace</var> is "<code>*</code>"
 (U+002A), return a {{HTMLCollection}} rooted at
 <var>root</var>, whose filter matches
 <a>descendant</a>
 <a for="/">elements</a> whose
 <a for=Element>local name</a> is
 <var>localName</var>.

 <li>Otherwise, if <var>localName</var> is "<code>*</code>"
 (U+002A), return a {{HTMLCollection}} rooted at
 <var>root</var>, whose filter matches
 <a>descendant</a>
 <a for="/">elements</a> whose
 <a for=Element>namespace</a> is
 <var>namespace</var>.

 <li>Otherwise, return a {{HTMLCollection}} rooted at
 <var>root</var>, whose filter matches
 <a>descendant</a>
 <a for="/">elements</a> whose
 <a for=Element>namespace</a> is
 <var>namespace</var> and
 <a for=Element>local name</a> is
 <var>localName</var>.
</ol>

When invoked with the same arguments, the same {{HTMLCollection}}
object may be returned as returned by an earlier call.


The
<dfn export id=concept-getelementsbyclassname>list of elements with class names <var>classNames</var></dfn>
for a <a>node</a> <var>root</var> is the
{{HTMLCollection}} returned by the following algorithm:
<ol>
 <li>
  Let <var>classes</var> be the result of running the
  <a>ordered set parser</a> on
  <var>classNames</var>.

 <li>
  If <var>classes</var> is the empty set, return an empty
  {{HTMLCollection}}.

 <li>
  <p>Return a {{HTMLCollection}} rooted at <var>root</var>,
  whose filter matches <a>descendant</a>
  <a for="/">elements</a> that have all their
  <a for=Element>classes</a> in <var>classes</var>.

  <p>The comparisons for the <a for=Element>classes</a> must be done in an
  <a>ASCII case-insensitive</a> manner if <var>root</var>'s <a for=Node>node document</a>'s
  <a for=Document>mode</a> is "<code>quirks</code>", and in a <a>case-sensitive</a> manner
  otherwise.
</ol>

When invoked with the same argument, the same {{HTMLCollection}}
object may be returned as returned by an earlier call.


<h3 id=interface-document>Interface {{Document}}</h3>

<pre class=idl force="Document">
[Exposed=Window]
interface Document : Node {
  constructor();

  [SameObject] readonly attribute DOMImplementation implementation;
  readonly attribute USVString URL;
  readonly attribute USVString documentURI;
  readonly attribute DOMString compatMode;
  readonly attribute DOMString characterSet;
  readonly attribute DOMString charset; // historical alias of .characterSet
  readonly attribute DOMString inputEncoding; // historical alias of .characterSet
  readonly attribute DOMString contentType;

  readonly attribute DocumentType? doctype;
  readonly attribute Element? documentElement;
  HTMLCollection getElementsByTagName(DOMString qualifiedName);
  HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
  HTMLCollection getElementsByClassName(DOMString classNames);

  [CEReactions, NewObject] Element createElement(DOMString localName, optional (DOMString or ElementCreationOptions) options = {});
  [CEReactions, NewObject] Element createElementNS(DOMString? namespace, DOMString qualifiedName, optional (DOMString or ElementCreationOptions) options = {});
  [NewObject] DocumentFragment createDocumentFragment();
  [NewObject] Text createTextNode(DOMString data);
  [NewObject] CDATASection createCDATASection(DOMString data);
  [NewObject] Comment createComment(DOMString data);
  [NewObject] ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data);

  [CEReactions, NewObject] Node importNode(Node node, optional boolean deep = false);
  [CEReactions] Node adoptNode(Node node);

  [NewObject] Attr createAttribute(DOMString localName);
  [NewObject] Attr createAttributeNS(DOMString? namespace, DOMString qualifiedName);

  [NewObject] Event createEvent(DOMString interface);

  [NewObject] Range createRange();

  // NodeFilter.SHOW_ALL = 0xFFFFFFFF
  [NewObject] NodeIterator createNodeIterator(Node root, optional unsigned long whatToShow = 0xFFFFFFFF, optional NodeFilter? filter = null);
  [NewObject] TreeWalker createTreeWalker(Node root, optional unsigned long whatToShow = 0xFFFFFFFF, optional NodeFilter? filter = null);
};

[Exposed=Window]
interface XMLDocument : Document {};

dictionary ElementCreationOptions {
  DOMString is;
};
</pre>

{{Document}} <a for=/>nodes</a> are simply
known as <dfn export id=concept-document lt="document">documents</dfn>.

Each <a>document</a> has an associated
<dfn export for=Document id=concept-document-encoding>encoding</dfn> (an <a for="/">encoding</a>),
<dfn export for=Document id=concept-document-content-type>content type</dfn> (a string),
<dfn export for=Document id=concept-document-url>URL</dfn> (a <a for=/>URL</a>),
<dfn export for=Document id=concept-document-origin>origin</dfn> (an <a for=/>origin</a>),
<dfn export for=Document id=concept-document-type>type</dfn> ("<code>xml</code>" or "<code>html</code>"), and
<dfn export for=Document id=concept-document-mode>mode</dfn> ("<code>no-quirks</code>", "<code>quirks</code>", or "<code>limited-quirks</code>").
[[!ENCODING]]
[[!URL]]
[[!HTML]]

Unless stated otherwise, a <a>document</a>'s <a for=Document>encoding</a> is the <a>utf-8</a>
<a for="/">encoding</a>, <a for=Document>content type</a> is
"<code>application/xml</code>", <a for=Document>URL</a> is "<code>about:blank</code>",
<a for=Document>origin</a> is an <a>opaque origin</a>,
<a for=Document>type</a> is "<code>xml</code>", and its
<a for=Document>mode</a> is "<code>no-quirks</code>".

A <a>document</a> is said to be an <dfn export>XML document</dfn> if its
<a for=Document>type</a> is "<code>xml</code>", and an <dfn export>HTML document</dfn>
otherwise. Whether a <a>document</a> is an <a>HTML document</a> or an <a>XML document</a>
affects the behavior of certain APIs.

A <a>document</a> is said to be in
<dfn export id=concept-document-no-quirks>no-quirks mode</dfn> if its
<a for=Document>mode</a> is "<code>no-quirks</code>",
<dfn export id=concept-document-quirks>quirks mode</dfn> if its <a for=Document>mode</a>
is "<code>quirks</code>", and
<dfn export id=concept-document-limited-quirks>limited-quirks mode</dfn> if its
<a for=Document>mode</a> is "<code>limited-quirks</code>".

<div class="note no-backref">
 <p>The <a for=Document>mode</a> is only ever changed from the default for <a>documents</a> created
 by the <a>HTML parser</a> based on the presence, absence, or value of the DOCTYPE string, and by a
 new <a for=/>browsing context</a> (initial "<code>about:blank</code>"). [[!HTML]]

 <p><a>No-quirks mode</a> was originally known as "standards mode" and <a>limited-quirks mode</a>
 was once known as "almost standards mode". They have been renamed because their details are now
 defined by standards. (And because Ian Hickson vetoed their original names on the basis that they
 are nonsensical.)
</div>

<p>A <a>document</a>'s <a>get the parent</a> algorithm, given an <var>event</var>, returns
null if <var>event</var>'s {{Event/type}} attribute value is "<code>load</code>" or
<a>document</a> does not have a <a for=Document>browsing context</a>, and the <a>document</a>'s
<a>relevant global object</a> otherwise.

<hr>

<dl class=domintro>
 <dt><code><var>document</var> = new {{Document()}}</code>
 <dd>Returns a new <a>document</a>.

 <dt><code><var>document</var> . {{Document/implementation}}</code>
 <dd>Returns <var>document</var>'s {{DOMImplementation}} object.

 <dt><code><var>document</var> . {{Document/URL}}</code>
 <dt><code><var>document</var> . {{Document/documentURI}}</code>
 <dd>Returns <var>document</var>'s <a for=Document>URL</a>.

 <dt><code><var>document</var> . {{Document/compatMode}}</code>
 <dd>
  Returns the string "<code>BackCompat</code>" if <var>document</var>'s
  <a for=Document>mode</a> is "<code>quirks</code>", and "<code>CSS1Compat</code>"
  otherwise.

 <dt><code><var>document</var> . {{Document/characterSet}}</code>
 <dd>Returns <var>document</var>'s
 <a for=Document>encoding</a>.

 <dt><code><var>document</var> . {{Document/contentType}}</code>
 <dd>Returns <var>document</var>'s
 <a for=Document>content type</a>.
</dl>

<p>The <dfn constructor for=Document><code>Document()</code></dfn> constructor, when invoked, must
return a new <a>document</a> whose <a for=Document>origin</a> is the <a for=Document>origin</a> of
<a>current global object</a>'s <a>associated <code>Document</code></a>. [[!HTML]]

<p class="note no-backref">Unlike {{DOMImplementation/createDocument()}}, this constructor does not
return an {{XMLDocument}} object, but a <a>document</a> ({{Document}} object).

The
<dfn attribute for=Document><code>implementation</code></dfn> attribute's getter must return the
{{DOMImplementation}} object that is associated with the <a>document</a>.

The <dfn attribute for=Document><code>URL</code></dfn> attribute's getter and
<dfn attribute for=Document><code>documentURI</code></dfn> attribute's getter must return the
<a for=Document>URL</a>, <a lt="URL serializer" spec=url>serialized</a>.

The <dfn attribute for=Document><code>compatMode</code></dfn> attribute's getter must
return "<code>BackCompat</code>" if <a>context object</a>'s <a for=Document>mode</a> is
"<code>quirks</code>", and "<code>CSS1Compat</code>" otherwise.

The <dfn attribute for=Document><code>characterSet</code></dfn> attribute's getter,
<dfn attribute for=Document><code>charset</code></dfn> attribute's getter, and
<dfn attribute for=Document><code>inputEncoding</code></dfn> attribute's getter, must return
<a>context object</a>'s <a for=Document>encoding</a>'s <a for=encoding>name</a>.

The <dfn attribute for=Document><code>contentType</code></dfn> attribute's getter must return the
<a for=Document>content type</a>.

<hr>

<dl class=domintro>
 <dt><var>document</var> . {{Document/doctype}}
 <dd>Returns the <a>doctype</a> or null if
 there is none.

 <dt><var>document</var> . {{Document/documentElement}}
 <dd>Returns the <a>document element</a>.

 <dt><var>collection</var> = <var>document</var> . {{Document/getElementsByTagName(qualifiedName)}}</code>

 <dd>
  <p>If <var>qualifiedName</var> is "<code>*</code>" returns a {{HTMLCollection}} of all
  <a>descendant</a> <a for="/">elements</a>.

  <p>Otherwise, returns a {{HTMLCollection}} of all <a>descendant</a> <a for="/">elements</a> whose
  <a for=Element>qualified name</a> is <var>qualifiedName</var>. (Matches case-insensitively against
  <a for="/">elements</a> in the <a>HTML namespace</a> within an <a>HTML document</a>.)

 <dt><var>collection</var> = <var>document</var> . {{Document/getElementsByTagNameNS(namespace, localName)}}</code>

 <dd>
  If <var>namespace</var> and <var>localName</var> are
  "<code>*</code>" returns a {{HTMLCollection}} of all
  <a>descendant</a>
  <a for="/">elements</a>.

  If only <var>namespace</var> is "<code>*</code>" returns a
  {{HTMLCollection}} of all
  <a>descendant</a>
  <a for="/">elements</a> whose
  <a for=Element>local name</a> is
  <var>localName</var>.

  If only <var>localName</var> is "<code>*</code>" returns a
  {{HTMLCollection}} of all
  <a>descendant</a>
  <a for="/">elements</a> whose
  <a for=Element>namespace</a> is
  <var>namespace</var>.

  Otherwise, returns a {{HTMLCollection}} of all
  <a>descendant</a>
  <a for="/">elements</a> whose
  <a for=Element>namespace</a> is
  <var>namespace</var> and
  <a for=Element>local name</a> is
  <var>localName</var>.

 <dt><var>collection</var> = <var>document</var> . {{Document/getElementsByClassName(classNames)}}</code>
 <dt><var>collection</var> = <var>element</var> . {{Element/getElementsByClassName(classNames)}}</code>
 <dd>
  Returns a {{HTMLCollection}} of the
  <a for="/">elements</a> in the object on which
  the method was invoked (a <a>document</a> or
  an <a for="/">element</a>) that have all the classes
  given by <var>classNames</var>.
  The <var>classNames</var> argument is interpreted as a
  space-separated list of classes.
</dl>

The <dfn attribute for=Document><code>doctype</code></dfn> attribute's getter must return the
<a for=tree>child</a> of the <a>document</a> that is a <a>doctype</a>, and null otherwise.

The <dfn attribute for=Document><code>documentElement</code></dfn> attribute's getter must return
the <a>document element</a>.

The <dfn method for=Document><code>getElementsByTagName(<var>qualifiedName</var>)</code></dfn>
method, when invoked, must return the
<a>list of elements with qualified name <var>qualifiedName</var></a> for the <a>context object</a>.

<p class="note no-backref">Thus, in an <a>HTML document</a>,
<code class='lang-javascript'>document.getElementsByTagName("FOO")</code> will match
<code>&lt;FOO></code> elements that are not in the
<a>HTML namespace</a>, and <code>&lt;foo></code> elements that are in
the <a>HTML namespace</a>, but not <code>&lt;FOO></code> elements
that are in the <a>HTML namespace</a>.

The
<dfn method for=Document><code>getElementsByTagNameNS(<var>namespace</var>, <var>localName</var>)</code></dfn>
method, when invoked, must return the
<a>list of elements with namespace <var>namespace</var> and local name <var>localName</var></a> for
the <a>context object</a>.

The <dfn method for=Document><code>getElementsByClassName(<var>classNames</var>)</code></dfn>
method, when invoked, must return the <a>list of elements with class names <var>classNames</var></a>
for the <a>context object</a>.

<div class=example id=example-5ffcda00>
 Given the following XHTML fragment:

 <pre><code class="lang-html">
  &lt;div id="example"&gt;
    &lt;p id="p1" class="aaa bbb"/&gt;
    &lt;p id="p2" class="aaa ccc"/&gt;
    &lt;p id="p3" class="bbb ccc"/&gt;
  &lt;/div&gt;
 </code></pre>

 A call to
 <code class="lang-javascript">document.getElementById("example").getElementsByClassName("aaa")</code>
 would return a {{HTMLCollection}} with the two paragraphs
 <code>p1</code> and <code>p2</code> in it.

 A call to
 <code class="lang-javascript">getElementsByClassName("ccc&nbsp;bbb")</code>
 would only return one node, however, namely <code>p3</code>. A call to
 <code class="lang-javascript">document.getElementById("example").getElementsByClassName("bbb&nbsp;&nbsp;ccc&nbsp;")</code>
 would return the same thing.

 A call to
 <code class="lang-javascript">getElementsByClassName("aaa,bbb")</code>
 would return no nodes; none of the elements above are in the
 <code>aaa,bbb</code> class.
</div>

<hr>

<dl class=domintro>
 <dt><code><var>element</var> = <var>document</var> . <a method for=Document lt=createElement()>createElement(localName [, options])</a></code>
 <dd>
  <p>Returns an <a for="/">element</a> with <var>localName</var> as <a for=Element>local name</a>
  (if <var>document</var> is an <a>HTML document</a>, <var>localName</var> gets lowercased). The
  <a for="/">element</a>'s <a for=Element>namespace</a> is the <a>HTML namespace</a> when
  <var>document</var> is an <a>HTML document</a> or <var>document</var>'s
  <a for=Document>content type</a> is "<code>application/xhtml+xml</code>", and null otherwise.

  <p>If <var>localName</var> does not match the <code><a type>Name</a></code> production an
  "{{InvalidCharacterError!!exception}}" {{DOMException}} will be thrown.

  <p>When supplied, <var>options</var>'s {{ElementCreationOptions/is}} can be used to create a
  <a>customized built-in element</a>.

 <dt><code><var>element</var> = <var>document</var> . <a method for=Document lt=createElementNS()>createElementNS(namespace, qualifiedName [, options])</a></code>

 <dd>
  <p>Returns an <a for="/">element</a> with <a for=Element>namespace</a> <var>namespace</var>. Its
  <a for=Element>namespace prefix</a> will be everything before "<code>:</code>" (U+003E) in
  <var>qualifiedName</var> or null. Its <a for=Element>local name</a> will be everything after
  "<code>:</code>" (U+003E) in <var>qualifiedName</var> or <var>qualifiedName</var>.

  <p>If <var>localName</var> does not match the <code><a type>Name</a></code> production an
  "{{InvalidCharacterError!!exception}}" {{DOMException}} will be thrown.

  <p>If one of the following conditions is true a "{{NamespaceError!!exception}}" {{DOMException}}
  will be thrown:

  <ul>
   <li><var>localName</var> does not match the
   <code><a type>QName</a></code> production.
   <li><a for=Element>Namespace prefix</a>
   is not null and <var>namespace</var> is the empty string.
   <li><a for=Element>Namespace prefix</a>
   is "<code>xml</code>" and <var>namespace</var> is not the
   <a>XML namespace</a>.
   <li><var>qualifiedName</var> or
   <a for=Element>namespace prefix</a>
   is "<code>xmlns</code>" and <var>namespace</var> is not the
   <a>XMLNS namespace</a>.
   <li><var>namespace</var> is the <a>XMLNS namespace</a> and
   neither <var>qualifiedName</var> nor
   <a for=Element>namespace prefix</a>
   is "<code>xmlns</code>".
  </ul>

  <p>When supplied, <var>options</var>'s {{ElementCreationOptions/is}} can be used to create a
  <a>customized built-in element</a>.

 <dt><code><var ignore>documentFragment</var> = <var>document</var> . {{createDocumentFragment()}}</code>
 <dd>Returns a {{DocumentFragment}}
 <a>node</a>.

 <dt><code><var ignore>text</var> = <var>document</var> . {{createTextNode(data)}}</code>
 <dd>Returns a {{Text}} <a>node</a>
 whose <a for=CharacterData>data</a> is <var>data</var>.

 <dt><code><var ignore>text</var> = <var>document</var> . {{createCDATASection(data)}}</code>
 <dd>Returns a {{CDATASection}} <a>node</a> whose <a for=CharacterData>data</a> is <var>data</var>.

 <dt><code><var ignore>comment</var> = <var>document</var> . {{createComment(data)}}</code>
 <dd>Returns a {{Comment}} <a>node</a>
 whose <a for=CharacterData>data</a> is <var>data</var>.

 <dt><code><var ignore>processingInstruction</var> = <var>document</var> . {{createProcessingInstruction(target, data)}}</code>
 <dd>
  Returns a {{ProcessingInstruction}}
  <a>node</a> whose
  <a for=ProcessingInstruction>target</a> is <var>target</var> and
  <a for=CharacterData>data</a> is <var>data</var>.
  If <var>target</var> does not match the
  <code><a type>Name</a></code> production an
  "{{InvalidCharacterError!!exception}}" {{DOMException}} will be thrown.
  If <var>data</var> contains "<code>?></code>" an
  "{{InvalidCharacterError!!exception}}" {{DOMException}} will be thrown.
</dl>

The <dfn export id=concept-element-interface>element interface</dfn> for any
<var>name</var> and <var>namespace</var> is {{Element}}, unless
stated otherwise.

<p class="note no-backref">The HTML Standard will e.g. define that for <code>html</code>
and the <a>HTML namespace</a>, the {{HTMLHtmlElement}} interface is used.
[[!HTML]]

The <dfn method for=Document><code>createElement(<var>localName</var>, <var>options</var>)</code></dfn> method, when
invoked, must run these steps:

<ol>
 <li><p>If <var>localName</var> does not match the <code><a type>Name</a></code> production, then
 <a>throw</a> an "{{InvalidCharacterError!!exception}}" {{DOMException}}.

 <li><p>If the <a>context object</a> is an <a>HTML document</a>, then set <var>localName</var> to
 <var>localName</var> in <a>ASCII lowercase</a>.

 <li><p>Let <var>is</var> be null.

 <li><p>If <var>options</var> is a <a for=/>dictionary</a> and <var>options</var>'s
 {{ElementCreationOptions/is}} is present, then set <var>is</var> to it.

 <li><p>Let <var>namespace</var> be the <a>HTML namespace</a>, if the <a>context object</a> is an
 <a>HTML document</a> or <a>context object</a>'s <a for=Document>content type</a> is
 "<code>application/xhtml+xml</code>", and null otherwise.

 <li><p>Return the result of <a>creating an element</a> given the <a>context object</a>,
 <var>localName</var>, <var>namespace</var>, null, <var>is</var>, and with the
 <var>synchronous custom elements</var> flag set.
</ol>

<p>The <dfn noexport>internal <code>createElementNS</code> steps</dfn>, given <var>document</var>,
<var>namespace</var>, <var>qualifiedName</var>, and <var>options</var>, are as follows:

<ol>
 <li><p>Let <var>namespace</var>, <var>prefix</var>, and <var>localName</var> be the result of
 passing <var>namespace</var> and <var>qualifiedName</var> to <a>validate and extract</a>.

 <li><p>Let <var>is</var> be null.

 <li><p>If <var>options</var> is a <a for=/>dictionary</a> and <var>options</var>'s
 {{ElementCreationOptions/is}} is present, then set <var>is</var> to it.

 <li><p>Return the result of <a>creating an element</a> given <var>document</var>,
 <var>localName</var>, <var>namespace</var>, <var>prefix</var>, <var>is</var>, and with the
 <var>synchronous custom elements</var> flag set.
</ol>

<p>The
<dfn method for=Document><code>createElementNS(<var>namespace</var>, <var>qualifiedName</var>, <var>options</var>)</code></dfn>
method, when invoked, must return the result of running the
<a>internal <code>createElementNS</code> steps</a>, given <a>context object</a>,
<var>namespace</var>, <var>qualifiedName</var>, and <var>options</var>.

<p class="note">{{Document/createElement()}} and {{Document/createElementNS()}}'s <var>options</var>
parameter is allowed to be a string for web compatibility.

The <dfn method for=Document><code>createDocumentFragment()</code></dfn> method, when invoked,
must return a new {{DocumentFragment}} <a>node</a> with its <a for=Node>node document</a> set to the
<a>context object</a>.

The <dfn method for=Document><code>createTextNode(<var>data</var>)</code></dfn> method, when
invoked, must return a new {{Text}} <a>node</a> with its <a for=CharacterData>data</a> set to <var>data</var> and
<a for=Node>node document</a> set to the <a>context object</a>.

<p class="note no-backref">No check is performed that <var>data</var> consists of
characters that match the <code><a type>Char</a></code> production.

<p>The <dfn method for=Document><code>createCDATASection(<var>data</var>)</code></dfn> method, when
invoked, must run these steps:

<ol>
 <li><p>If <a>context object</a> is an <a>HTML document</a>, then <a>throw</a> a
 "{{NotSupportedError!!exception}}" {{DOMException}}.

 <li><p>If <var>data</var> contains the string "<code>]]></code>", then <a>throw</a> an
 "{{InvalidCharacterError!!exception}}" {{DOMException}}.

 <li><p>Return a new {{CDATASection}} <a>node</a> with its <a for=CharacterData>data</a> set to <var>data</var> and
 <a for=Node>node document</a> set to the <a>context object</a>.
</ol>

The <dfn method for=Document><code>createComment(<var>data</var>)</code></dfn> method, when invoked,
must return a new {{Comment}} <a>node</a> with its <a for=CharacterData>data</a> set to <var>data</var> and
<a for=Node>node document</a> set to the <a>context object</a>.

<p class="note no-backref">No check is performed that <var>data</var> consists of
characters that match the <code><a type>Char</a></code> production
or that it contains two adjacent hyphens or ends with a hyphen.

The
<dfn method for=Document><code>createProcessingInstruction(<var>target</var>, <var>data</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li>If <var>target</var> does not match the
 <!--<code data-anolis-type>PITarget</code>-->
 <code><a type>Name</a></code> production,
 then <a>throw</a> an "{{InvalidCharacterError!!exception}}" {{DOMException}}. <!-- DOM3 does not check for "xml" -->

 <li>If <var>data</var> contains the string
 "<code>?></code>", then <a>throw</a> an
 "{{InvalidCharacterError!!exception}}" {{DOMException}}. <!-- Gecko does this. -->

 <li>Return a new {{ProcessingInstruction}}
 <a>node</a>, with
 <a for=ProcessingInstruction>target</a> set to <var>target</var>,
 <a for=CharacterData>data</a> set to <var>data</var>, and
 <a for=Node>node document</a> set to the
 <a>context object</a>.
</ol>

<p class="note no-backref">No check is performed that <var>target</var> contains
"<code>xml</code>" or "<code>:</code>", or that
<var>data</var> contains characters that match the
<code><a type>Char</a></code> production.

<hr>

<dl class=domintro>
 <dt><var>clone</var> = <var>document</var> . <a method for=Document lt=importNode()>importNode(<var>node</var> [, <var>deep</var> = false])</a>
 <dd>
  Returns a copy of <var>node</var>. If
  <var>deep</var> is true, the copy also includes the
  <var>node</var>'s <a>descendants</a>.

  If <var>node</var> is a <a>document</a> or a <a for=/>shadow root</a>, throws a
  "{{NotSupportedError!!exception}}" {{DOMException}}.

 <dt><var>node</var> = <var>document</var> . {{adoptNode(node)}}

 <dd>
  Moves <var>node</var> from another
  <a>document</a> and returns it.

  If <var>node</var> is a <a>document</a>, throws a "{{NotSupportedError!!exception}}"
  {{DOMException}} or, if <var>node</var> is a <a for=/>shadow root</a>, throws a
  "{{HierarchyRequestError!!exception}}" {{DOMException}}.
</dl>

The <dfn method for=Document><code>importNode(<var>node</var>, <var>deep</var>)</code></dfn> method,
when invoked, must run these steps:

<ol>
 <li><p>If <var>node</var> is a <a>document</a> or <a for=/>shadow root</a>, then <a>throw</a> a
 "{{NotSupportedError!!exception}}" {{DOMException}}.

 <li><p>Return a <a lt="clone a node">clone</a> of <var>node</var>, with <a>context object</a> and
 the <i>clone children flag</i> set if <var>deep</var> is true.
</ol>

<p><a lt="Other applicable specifications">Specifications</a> may define
<dfn export id=concept-node-adopt-ext>adopting steps</dfn> for all or some <a for=/>nodes</a>. The
algorithm is passed <var>node</var> and <var>oldDocument</var>, as indicated in the <a>adopt</a>
algorithm.

<p>To <dfn export id=concept-node-adopt>adopt</dfn> a <var>node</var> into a <var>document</var>, run
these steps:

<ol>
 <li><p>Let <var>oldDocument</var> be <var>node</var>'s <a for=Node>node document</a>.

 <li><p>If <var>node</var>'s <a for=tree>parent</a> is non-null, then <a for=/>remove</a>
 <var>node</var>.

 <li>
  <p>If <var>document</var> is not <var>oldDocument</var>, then:

  <ol>
   <li>
    <p>For each <var>inclusiveDescendant</var> in <var>node</var>'s
    <a>shadow-including inclusive descendants</a>:

    <ol>
     <li><p>Set <var>inclusiveDescendant</var>'s <a for=Node>node document</a> to <var>document</var>.

     <li><p>If <var>inclusiveDescendant</var> is an <a for=/>element</a>, then set the
     <a for=Node>node document</a> of each <a>attribute</a> in <var>inclusiveDescendant</var>'s
     <a for=Element>attribute list</a> to <var>document</var>.
    </ol>

   <li><p>For each <var>inclusiveDescendant</var> in <var>node</var>'s
   <a>shadow-including inclusive descendants</a> that is <a for=Element>custom</a>,
   <a>enqueue a custom element callback reaction</a> with <var>inclusiveDescendant</var>, callback
   name "<code>adoptedCallback</code>", and an argument list containing <var>oldDocument</var> and
   <var>document</var>. <!-- attributeChangedCallback is also old, then new -->

   <li><p>For each <var>inclusiveDescendant</var> in <var>node</var>'s
   <a>shadow-including inclusive descendants</a>, in <a>shadow-including tree order</a>, run the
   <a>adopting steps</a> with <var>inclusiveDescendant</var> and <var>oldDocument</var>.
  </ol>
</ol>

The <dfn method for=Document><code>adoptNode(<var>node</var>)</code></dfn> method, when invoked,
must run these steps:

<ol>
 <li><p>If <var>node</var> is a <a>document</a>, then <a>throw</a> a
 "{{NotSupportedError!!exception}}" {{DOMException}}.

 <li><p>If <var>node</var> is a <a for=/>shadow root</a>, then <a>throw</a> a
 "{{HierarchyRequestError!!exception}}" {{DOMException}}.

 <li><p>If <var>node</var> is a {{DocumentFragment}} <a for=/>node</a> whose
 <a for=DocumentFragment>host</a> is non-null, then return.

 <li><p><a>Adopt</a> <var>node</var> into the <a>context object</a>.

 <li><p>Return <var>node</var>.
</ol>

<hr>

The <dfn method for=Document><code>createAttribute(<var>localName</var>)</code></dfn> method, when
invoked, must run these steps:

<ol>
 <li><p>If <var>localName</var> does not match the <code><a type>Name</a></code> production in XML,
 then <a>throw</a> an "{{InvalidCharacterError!!exception}}" {{DOMException}}.

 <li>If the <a>context object</a> is an <a>HTML document</a>, then set <var>localName</var> to
 <var>localName</var> in <a>ASCII lowercase</a>.

 <li>Return a new <a>attribute</a> whose <a for=Attr>local name</a> is <var>localName</var> and
 <a for=Node>node document</a> is <a>context object</a>.
</ol>

The
<dfn method for=Document><code>createAttributeNS(<var>namespace</var>, <var>qualifiedName</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li><p>Let <var>namespace</var>, <var>prefix</var>, and <var>localName</var> be the result of
 passing <var>namespace</var> and <var>qualifiedName</var> to <a>validate and extract</a>.

 <li><p>Return a new <a>attribute</a> whose <a for=Attr>namespace</a> is <var>namespace</var>,
 <a for=Attr>namespace prefix</a> is <var>prefix</var>, <a for=Attr>local name</a> is
 <var>localName</var>, and <a for=Node>node document</a> is <a>context object</a>.
</ol>

<hr>

<p>The <dfn method for=Document><code>createEvent(<var>interface</var>)</code></dfn> method, when
invoked, must run these steps:

<ol>
 <li><p>Let <var>constructor</var> be null.

 <li>
  <p>If <var>interface</var> is an <a>ASCII case-insensitive</a> match for any of the strings in the
  first column in the following table, then set <var>constructor</var> to the interface in the
  second column on the same row as the matching string:

  <table>
   <thead>
    <tr><th>String<th>Interface<td>Notes
   <tbody>
    <tr><td>"<code>beforeunloadevent</code>"<td>{{BeforeUnloadEvent}}<td>[[!HTML]]
    <tr><td>"<code>compositionevent</code>"<td>{{CompositionEvent}}<td>[[!UIEVENTS]]
    <!-- textevent also maps to CompositionEvent -->
    <tr><td>"<code>customevent</code>"<td>{{CustomEvent}}<td>
    <tr><td>"<code>devicemotionevent</code>"<td>{{DeviceMotionEvent}}<td rowspan=2>[[!DEVICE-ORIENTATION]]
    <tr><td>"<code>deviceorientationevent</code>"<td>{{DeviceOrientationEvent}}
    <tr><td>"<code>dragevent</code>"<td>{{DragEvent}}<td>[[!HTML]]
    <tr><td>"<code>event</code>"<td rowspan=2>{{Event}}<td rowspan=2>
    <tr><td>"<code>events</code>"
    <!-- htmlevents and svgevents also map to Event -->
    <tr><td>"<code>focusevent</code>"<td>{{FocusEvent}}<td>[[!UIEVENTS]]
    <tr><td>"<code>hashchangeevent</code>"<td>{{HashChangeEvent}}<td>[[!HTML]]
    <tr><td>"<code>htmlevents</code>"<td>{{Event}}<td>
    <tr><td>"<code>keyboardevent</code>"<td>{{KeyboardEvent}}<td>[[!UIEVENTS]]
    <tr><td>"<code>messageevent</code>"<td>{{MessageEvent}}<td>[[!HTML]]
    <tr><td>"<code>mouseevent</code>"<td rowspan=2>{{MouseEvent}}<td rowspan=2>[[!UIEVENTS]]
    <tr><td>"<code>mouseevents</code>"
    <tr><td>"<code>storageevent</code>"<td>{{StorageEvent}}<td>[[!HTML]]
    <tr><td>"<code>svgevents</code>"<td>{{Event}}<td>
    <tr><td>"<code>textevent</code>"<td>{{CompositionEvent}}<td>[[!UIEVENTS]]
    <tr><td>"<code>touchevent</code>"<td>{{TouchEvent}}<td>[[!TOUCH-EVENTS]]
    <tr><td>"<code>uievent</code>"<td rowspan=2>{{UIEvent}}<td rowspan=2>[[!UIEVENTS]]
    <tr><td>"<code>uievents</code>"
  </table>

 <li><p>If <var>constructor</var> is null, then <a>throw</a> a "{{NotSupportedError!!exception}}"
  {{DOMException}}.

 <li>
  <p>If the interface indicated by <var>constructor</var> is not exposed on the <a>relevant global
  object</a> of the <a>context object</a>, then <a>throw</a> a "{{NotSupportedError!!exception}}"
  {{DOMException}}.

  <p class=note>Typically user agents disable support for touch events in some configurations, in
  which case this clause would be triggered for the interface {{TouchEvent}}.

 <li><p>Let <var>event</var> be the result of <a>creating an event</a> given <var>constructor</var>.

 <li><p>Initialize <var>event</var>'s {{Event/type}} attribute to the empty string.

 <li><p>Initialize <var>event</var>'s {{Event/timeStamp}} attribute to a {{DOMHighResTimeStamp}}
 representing the high resolution time from the <a>time origin</a> to now.

 <li><p>Initialize <var>event</var>'s {{Event/isTrusted}} attribute to false.

 <li><p>Unset <var>event</var>'s <a>initialized flag</a>.

 <li><p>Return <var>event</var>.
</ol>

<p class=note><a>Event</a> constructors ought to be used instead.

<hr>

<p>The <dfn method for=Document><code>createRange()</code></dfn> method, when invoked, must return a
new <a>live range</a> with (<a>context object</a>, 0) as its <a for=range>start</a> and
<a for=range>end</a>.

<p class=note>The {{Range/Range()}} constructor can be used instead.

<hr>

<p>The
<dfn method for=Document><code>createNodeIterator(<var>root</var>, <var>whatToShow</var>, <var>filter</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li><p>Let <var>iterator</var> be a new {{NodeIterator}} object.

 <li><p>Set <var>iterator</var>'s <a for=traversal>root</a> and <var>iterator</var>'s
 <a for=NodeIterator>reference</a> to <var>root</var>.

 <li><p>Set <var>iterator</var>'s <a for=NodeIterator>pointer before reference</a> to true.

 <li><p>Set <var>iterator</var>'s <a for=traversal>whatToShow</a> to <var>whatToShow</var>.

 <li><p>Set <var>iterator</var>'s <a for=traversal>filter</a> to <var>filter</var>.

 <li><p>Return <var>iterator</var>.
</ol>

<p>The
<dfn method for=Document><code>createTreeWalker(<var>root</var>, <var>whatToShow</var>, <var>filter</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li><p>Let <var>walker</var> be a new {{TreeWalker}} object.

 <li><p>Set <var>walker</var>'s <a for=traversal>root</a> and <var>walker</var>'s
 <a for=TreeWalker>current</a> to <var>root</var>.

 <li><p>Set <var>walker</var>'s <a for=traversal>whatToShow</a> to <var>whatToShow</var>.

 <li><p>Set <var>walker</var>'s <a for=traversal>filter</a> to <var>filter</var>.

 <li>Return <var>walker</var>.
</ol>


<h4 id=interface-domimplementation>Interface {{DOMImplementation}}</h4>

User agents must create a {{DOMImplementation}} object whenever
a <a>document</a> is created and associate it
with that <a>document</a>.

<pre class=idl>
[Exposed=Window]
interface DOMImplementation {
  [NewObject] DocumentType createDocumentType(DOMString qualifiedName, DOMString publicId, DOMString systemId);
  [NewObject] XMLDocument createDocument(DOMString? namespace, [TreatNullAs=EmptyString] DOMString qualifiedName, optional DocumentType? doctype = null);
  [NewObject] Document createHTMLDocument(optional DOMString title);

  boolean hasFeature(); // useless; always returns true
};
</pre>

<dl class=domintro>
 <dt><code><var>doctype</var> = <var>document</var> . {{Document/implementation}} . {{createDocumentType(qualifiedName, publicId, systemId)}}</code>

 <dd>
  Returns a <a>doctype</a>, with the given
  <var>qualifiedName</var>, <var>publicId</var>, and
  <var>systemId</var>. If <var>qualifiedName</var> does not
  match the <code><a type>Name</a></code> production, an
  "{{InvalidCharacterError!!exception}}" {{DOMException}} is thrown, and if it does not match the
  <code><a type>QName</a></code> production, a
  "{{NamespaceError!!exception}}" {{DOMException}} is thrown.

 <dt><code><var>doc</var> = <var>document</var> . {{Document/implementation}} . <a method for=DOMImplementation lt=createDocument()>createDocument(<var>namespace</var>, <var>qualifiedName</var> [, <var>doctype</var> = null])</a></code>

 <dd>
  Returns an {{XMLDocument}}, with a
  <a>document element</a> whose
  <a for=Element>local name</a> is
  <var>qualifiedName</var> and whose
  <a for=Element>namespace</a> is
  <var>namespace</var> (unless <var>qualifiedName</var> is the
  empty string), and with <var>doctype</var>, if it is given, as its
  <a>doctype</a>.

  This method throws the same exceptions as the {{Document/createElementNS()}} method, when
  invoked with <var>namespace</var> and <var>qualifiedName</var>.

 <dt><code><var>doc</var> = <var>document</var> . {{Document/implementation}} . <a method for=DOMImplementation lt=createHTMLDocument()>createHTMLDocument([<var>title</var>])</a></code>

 <dd>
  Returns a <a>document</a>, with a basic
  <a>tree</a> already constructed including a
  <{title}> element, unless the <var>title</var>
  argument is omitted.
</dl>

<div class=impl>

The
<dfn method for=DOMImplementation><code>createDocumentType(<var>qualifiedName</var>, <var>publicId</var>, <var>systemId</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li><p><a>Validate</a> <var>qualifiedName</var>.

 <li><p>Return a new <a>doctype</a>, with <var>qualifiedName</var> as its
 <a for=DocumentType>name</a>, <var>publicId</var> as its <a>public ID</a>, and <var>systemId</var>
 as its <a>system ID</a>, and with its <a for=Node>node document</a> set to the associated <a>document</a> of
 the <a>context object</a>.
</ol>

<p class=note>No check is performed that <var>publicId</var> code points match the
<code><a type>PubidChar</a></code> production or that <var>systemId</var> does not contain both a
'<code>"</code>' and a "<code>'</code>".

<p>The
<dfn method for=DOMImplementation><code>createDocument(<var>namespace</var>, <var>qualifiedName</var>, <var>doctype</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li><p>Let <var>document</var> be a new {{XMLDocument}}.

 <li><p>Let <var>element</var> be null.

 <li><p>If <var>qualifiedName</var> is not the empty string, then set <var>element</var> to the
 result of running the <a>internal <code>createElementNS</code> steps</a>, given
 <var>document</var>, <var>namespace</var>, <var>qualifiedName</var>, and an empty dictionary.

 <li><p>If <var>doctype</var> is non-null, <a>append</a> <var>doctype</var> to <var>document</var>.

 <li><p>If <var>element</var> is non-null, <a>append</a> <var>element</var> to <var>document</var>.

 <li><p><var>document</var>'s <a for=Document>origin</a> is <a>context object</a>'s associated
 <a>document</a>'s <a for=Document>origin</a>.

 <li>
  <p><var>document</var>'s <a for=Document>content type</a> is determined by <var>namespace</var>:

  <dl class=switch>
   <dt><a>HTML namespace</a>
   <dd><code>application/xhtml+xml</code>

   <dt><a>SVG namespace</a>
   <dd><code>image/svg+xml</code>

   <dt>Any other namespace
   <dd><code>application/xml</code>
  </dl>

 <li><p>Return <var>document</var>.
</ol>

The
<dfn method for=DOMImplementation><code>createHTMLDocument(<var>title</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li><p>Let <var>doc</var> be a new <a>document</a> that is an <a>HTML document</a>.

 <li><p>Set <var>doc</var>'s <a for=Document>content type</a> to "<code>text/html</code>".

 <li><p><a>Append</a> a new <a>doctype</a>, with "<code>html</code>" as its
 <a for=DocumentType>name</a> and with its <a for=Node>node document</a> set to <var>doc</var>, to
 <var>doc</var>.

 <li><p><a>Append</a> the result of <a>creating an element</a> given <var>doc</var>, <{html}>, and
 the <a>HTML namespace</a>, to <var>doc</var>.

 <li><p><a>Append</a> the result of <a>creating an element</a> given <var>doc</var>, <{head}>, and
 the <a>HTML namespace</a>, to the <{html}> element created earlier.

 <li>
  <p>If <var>title</var> is given:

  <ol>
   <li><p><a>Append</a> the result of <a>creating an element</a> given <var>doc</var>, <{title}>,
   and the <a>HTML namespace</a>, to the <{head}> element created earlier.

   <li><p><a>Append</a> a new {{Text}} <a>node</a>, with its <a for=CharacterData>data</a> set to
   <var>title</var> (which could be the empty string) and its <a for=Node>node document</a> set to
   <var>doc</var>, to the <{title}> element created earlier.
  </ol>

 <li><p><a>Append</a> the result of <a>creating an element</a> given <var>doc</var>, <{body}>, and
 the <a>HTML namespace</a>, to the <{html}> element created earlier.</li>

 <li><p><var>doc</var>'s <a for=Document>origin</a> is <a>context object</a>'s associated
 <a>document</a>'s <a for=Document>origin</a>.

 <li><p>Return <var>doc</var>.
</ol>

The <dfn method for="DOMImplementation"><code>hasFeature()</code></dfn> method, when
invoked, must return true.

<p class="note no-backref">{{hasFeature()}} originally would report whether the user agent
claimed to support a given DOM feature, but experience proved it was not nearly as
reliable or granular as simply checking whether the desired objects, attributes, or
methods existed. As such, it is no longer to be used, but continues to exist (and simply
returns true) so that old pages don't stop working.

</div>


<h3 id=interface-documenttype>Interface {{DocumentType}}</h3>

<pre class=idl>
[Exposed=Window]
interface DocumentType : Node {
  readonly attribute DOMString name;
  readonly attribute DOMString publicId;
  readonly attribute DOMString systemId;
};
</pre>

<p>{{DocumentType}} <a for=/>nodes</a> are simply known as
<dfn export id=concept-doctype lt="doctype">doctypes</dfn>.

<p><a>Doctypes</a> have an associated
<dfn export id=concept-doctype-name for=DocumentType>name</dfn>,
<dfn export id=concept-doctype-publicid for=DocumentType>public ID</dfn>, and
<dfn export id=concept-doctype-systemid for=DocumentType>system ID</dfn>.

<p>When a <a>doctype</a> is created, its <a for=DocumentType>name</a> is always given. Unless
explicitly given when a <a>doctype</a> is created, its <a>public ID</a> and <a>system ID</a> are the
empty string.

<p>The <dfn attribute for=DocumentType><code>name</code></dfn> attribute's getter must return the
<a>context object</a>'s <a for=DocumentType>name</a>.

<p>The <dfn attribute for=DocumentType><code>publicId</code></dfn> attribute's getter must return
the <a>context object</a>'s <a>public ID</a>.

<p>The <dfn attribute for=DocumentType><code>systemId</code></dfn> attribute's getter must return
the <a>context object</a>'s <a>system ID</a>.


<h3 id=interface-documentfragment>Interface {{DocumentFragment}}</h3>

<pre class=idl>
[Exposed=Window]
interface DocumentFragment : Node {
  constructor();
};
</pre>

<p>A {{DocumentFragment}} <a>node</a> has an associated
<dfn export id=concept-documentfragment-host for=DocumentFragment>host</dfn> (null or an
<a for="/">element</a> in a different <a>node tree</a>). It is null unless otherwise stated.

<p>An object <var>A</var> is a
<dfn export id=concept-tree-host-including-inclusive-ancestor>host-including inclusive ancestor</dfn>
of an object <var>B</var>, if either <var>A</var> is an <a for=tree>inclusive ancestor</a> of <var>B</var>,
or if <var>B</var>'s <a for=tree>root</a> has a non-null <a for=DocumentFragment>host</a> and
<var>A</var> is a <a>host-including inclusive ancestor</a> of <var>B</var>'s <a for=tree>root</a>'s
<a for=DocumentFragment>host</a>.

<p class="note no-backref">The {{DocumentFragment}} <a>node</a>'s <a for=DocumentFragment>host</a>
concept is useful for HTML's <{template}> element and for <a for=/>shadow roots</a>, and impacts the
<a>pre-insert</a> and <a>replace</a> algorithms.

<dl class=domintro>
 <dt><code><var ignore>tree</var> = new {{DocumentFragment()}}</code>
 <dd>Returns a new {{DocumentFragment}} <a>node</a>.
</dl>

<p>The <dfn constructor for=DocumentFragment><code>DocumentFragment()</code></dfn> constructor, when
invoked, must return a new {{DocumentFragment}} <a>node</a> whose <a for=Node>node document</a> is
<a>current global object</a>'s <a>associated <code>Document</code></a>.


<h3 id=interface-shadowroot>Interface {{ShadowRoot}}</h3>

<pre class=idl>
[Exposed=Window]
interface ShadowRoot : DocumentFragment {
  readonly attribute ShadowRootMode mode;
  readonly attribute Element host;
  attribute EventHandler onslotchange;
};

enum ShadowRootMode { "open", "closed" };
</pre>

<p>{{ShadowRoot}} <a for=/>nodes</a> are simply known as
<dfn export id=concept-shadow-root lt="shadow root">shadow roots</dfn>.

<p><a for=/>Shadow roots</a> have an associated <dfn for=ShadowRoot>mode</dfn> ("<code>open</code>"
or "<code>closed</code>").</p>

<p><a for=/>Shadow roots</a> have an associated <dfn export for=ShadowRoot>delegates focus</dfn>.
It is initially set to false.</p>

<p><a for=/>Shadow roots</a>'s associated <a for=DocumentFragment>host</a> is never null.</p>
<!-- If we ever change this, e.g., add a ShadowRoot object constructor, that would have serious
     consequences for innerHTML. -->

<p>A <a for=/>shadow root</a>'s <a>get the parent</a> algorithm, given an <var>event</var>, returns
null if <var>event</var>'s <a>composed flag</a> is unset and <a for=/>shadow root</a> is the
<a for=tree>root</a> of <var>event</var>'s <a for=Event>path</a>'s first struct's
<a for=Event/path>invocation target</a>, and <a for=/>shadow root</a>'s
<a for=DocumentFragment>host</a> otherwise.

<p>The <dfn attribute for=ShadowRoot><code>mode</code></dfn> attribute's getter must return the
<a>context object</a>'s <a for=ShadowRoot>mode</a>.</p>

<p>The <dfn attribute for=ShadowRoot><code>host</code></dfn> attribute's getter must return the
<a>context object</a>'s <a for=DocumentFragment>host</a>.

<p>The <dfn attribute for=ShadowRoot><code>onslotchange</code></dfn> attribute is an
<a>event handler IDL attribute</a> for the
<dfn for=ShadowRoot export><code>onslotchange</code></dfn> <a>event handler</a>, whose
<a>event handler event type</a> is {{HTMLSlotElement/slotchange}}.

<hr>

<p>In <dfn export id=concept-shadow-including-tree-order>shadow-including tree order</dfn> is
<a>shadow-including preorder, depth-first traversal</a> of a <a>node tree</a>.
<dfn noexport>Shadow-including preorder, depth-first traversal</dfn> of a <a>node tree</a>
<var>tree</var> is preorder, depth-first traversal of <var>tree</var>, with for each
<a for=Element>shadow host</a> encountered in <var>tree</var>,
<a>shadow-including preorder, depth-first traversal</a> of that <a for=/>element</a>'s
<a for=Element>shadow root</a>'s <a>node tree</a> just after it is encountered.

<p>The <dfn export id=concept-shadow-including-root>shadow-including root</dfn> of an object is its
<a for=tree>root</a>'s <a for=DocumentFragment>host</a>'s <a>shadow-including root</a>, if the
object's <a for=tree>root</a> is a <a for=/>shadow root</a>, and its <a for=tree>root</a>
otherwise.</p>

<p>An object <var>A</var> is a
<dfn export id=concept-shadow-including-descendant>shadow-including descendant</dfn> of an object
<var>B</var>, if <var>A</var> is a <a>descendant</a> of <var>B</var>, or <var>A</var>'s
<a for=tree>root</a> is a <a for=/>shadow root</a> and <var>A</var>'s <a for=tree>root</a>'s
<a for=DocumentFragment>host</a> is a <a>shadow-including inclusive descendant</a> of <var>B</var>.

<p>A
<dfn export id=concept-shadow-including-inclusive-descendant>shadow-including inclusive descendant</dfn>
is an object or one of its <a>shadow-including descendants</a>.

<p>An object <var>A</var> is a
<dfn export id=concept-shadow-including-ancestor>shadow-including ancestor</dfn> of an object
<var>B</var>, if and only if <var>B</var> is a <a>shadow-including descendant</a> of <var>A</var>.

<p>A
<dfn export id=concept-shadow-including-inclusive-ancestor>shadow-including inclusive ancestor</dfn>
is an object or one of its <a>shadow-including ancestors</a>.

<p>A <a>node</a> <var>A</var> is
<dfn export id=concept-closed-shadow-hidden>closed-shadow-hidden</dfn> from a <a>node</a>
<var>B</var> if all of the following conditions are true:

<ul>
 <li><p><var>A</var>'s <a for=tree>root</a> is a <a for=/>shadow root</a>.

 <li><p><var>A</var>'s <a for=tree>root</a> is not a <a>shadow-including inclusive ancestor</a> of
 <var>B</var>.

 <li><p><var>A</var>'s <a for=tree>root</a> is a <a for=/>shadow root</a> whose
 <a for=ShadowRoot>mode</a> is "<code>closed</code>" or <var>A</var>'s <a for=tree>root</a>'s
 <a for=DocumentFragment>host</a> is <a>closed-shadow-hidden</a> from <var>B</var>.
</ul>

<p>To <dfn export lt="retarget|retargeting">retarget</dfn> an object <var>A</var> against an object
<var>B</var>, repeat these steps until they return an object:</p>

<ol>
 <li>
  <p>If one of the following is true

  <ul class=brief>
   <li><var>A</var> is not a <a>node</a>
   <li><var>A</var>'s <a for=tree>root</a> is not a <a for=/>shadow root</a>
   <li><var>B</var> is a <a>node</a> and <var>A</var>'s <a for=tree>root</a> is a
   <a>shadow-including inclusive ancestor</a> of <var>B</var>
  </ul>

  <p>then return <var>A</var>.

 <li><p>Set <var>A</var> to <var>A</var>'s <a for=tree>root</a>'s <a for=DocumentFragment>host</a>.
</ol>

<p class=note>The <a>retargeting</a> algorithm is used by <a lt=dispatch>event dispatch</a> as well
as other specifications, such as <cite>Fullscreen</cite>. [[FULLSCREEN]]


<h3 id=interface-element>Interface {{Element}}</h3>

<pre class=idl>
[Exposed=Window]
interface Element : Node {
  readonly attribute DOMString? namespaceURI;
  readonly attribute DOMString? prefix;
  readonly attribute DOMString localName;
  readonly attribute DOMString tagName;

  [CEReactions] attribute DOMString id;
  [CEReactions] attribute DOMString className;
  [SameObject, PutForwards=value] readonly attribute DOMTokenList classList;
  [CEReactions, Unscopable] attribute DOMString slot;

  boolean hasAttributes();
  [SameObject] readonly attribute NamedNodeMap attributes;
  sequence&lt;DOMString> getAttributeNames();
  DOMString? getAttribute(DOMString qualifiedName);
  DOMString? getAttributeNS(DOMString? namespace, DOMString localName);
  [CEReactions] void setAttribute(DOMString qualifiedName, DOMString value);
  [CEReactions] void setAttributeNS(DOMString? namespace, DOMString qualifiedName, DOMString value);
  [CEReactions] void removeAttribute(DOMString qualifiedName);
  [CEReactions] void removeAttributeNS(DOMString? namespace, DOMString localName);
  [CEReactions] boolean toggleAttribute(DOMString qualifiedName, optional boolean force);
  boolean hasAttribute(DOMString qualifiedName);
  boolean hasAttributeNS(DOMString? namespace, DOMString localName);

  Attr? getAttributeNode(DOMString qualifiedName);
  Attr? getAttributeNodeNS(DOMString? namespace, DOMString localName);
  [CEReactions] Attr? setAttributeNode(Attr attr);
  [CEReactions] Attr? setAttributeNodeNS(Attr attr);
  [CEReactions] Attr removeAttributeNode(Attr attr);

  ShadowRoot attachShadow(ShadowRootInit init);
  readonly attribute ShadowRoot? shadowRoot;

  Element? closest(DOMString selectors);
  boolean matches(DOMString selectors);
  boolean webkitMatchesSelector(DOMString selectors); // historical alias of .matches

  HTMLCollection getElementsByTagName(DOMString qualifiedName);
  HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
  HTMLCollection getElementsByClassName(DOMString classNames);

  [CEReactions] Element? insertAdjacentElement(DOMString where, Element element); // historical
  void insertAdjacentText(DOMString where, DOMString data); // historical
};

dictionary ShadowRootInit {
  required ShadowRootMode mode;
  boolean delegatesFocus = false;
};
</pre>

<p>{{Element}} <a for=/>nodes</a> are simply known as
<dfn export id=concept-element lt=element>elements</dfn>.

<p><a for=/>Elements</a> have an associated
<dfn export id=concept-element-namespace for=Element>namespace</dfn>,
<dfn export id=concept-element-namespace-prefix for=Element>namespace prefix</dfn>,
<dfn export id=concept-element-local-name for=Element>local name</dfn>,
<dfn export id=concept-element-custom-element-state for=Element>custom element state</dfn>,
<dfn export id=concept-element-custom-element-definition for=Element>custom element definition</dfn>,
<dfn export id=concept-element-is-value for=Element><code>is</code> value</dfn>. When an
<a for="/">element</a> is <a lt="create an element">created</a>, all of these values are
initialized.

<p>An <a for=/>element</a>'s <a for=Element>custom element state</a> is one of
"<code>undefined</code>", "<code>failed</code>", "<code>uncustomized</code>", or
"<code>custom</code>". An <a for=/>element</a> whose <a for=Element>custom element state</a> is
"<code>uncustomized</code>" or "<code>custom</code>" is said to be
<dfn export id=concept-element-defined for=Element>defined</dfn>. An <a for=/>element</a> whose
<a for=Element>custom element state</a> is "<code>custom</code>" is said to be
<dfn export id=concept-element-custom for=Element>custom</dfn>.

<p class=note>Whether or not an element is <a for=Element>defined</a> is used to determine the
behavior of the '':defined'' pseudo-class. Whether or not an element is <a for=Element>custom</a> is
used to determine the behavior of the <a href=#mutation-algorithms>mutation algorithms</a>. The
"<code>failed</code>" state is used to ensure that if a <a>custom element constructor</a> fails to
execute correctly the first time, it is not executed again by an
<a lt="upgrade an element">upgrade</a>.</p>

<div class=example id=example-c5b21302>
 <p>The following code illustrates elements in each of these four states:</p>

 <pre><code class="lang-html">
  &lt;!DOCTYPE html>
  &lt;script>
    window.customElements.define("sw-rey", class extends HTMLElement {})
    window.customElements.define("sw-finn", class extends HTMLElement {}, { extends: "p" })
    window.customElements.define("sw-kylo", class extends HTMLElement {
      constructor() {
        // super() intentionally omitted for this example
      }
    })
  &lt;/script>

  &lt;!-- "undefined" (not defined, not custom) -->
  &lt;sw-han>&lt;/sw-han>
  &lt;p is="sw-luke">&lt;/p>
  &lt;p is="asdf">&lt;/p>

  &lt;!-- "failed" (not defined, not custom) -->
  &lt;sw-kylo>&lt;/sw-kylo>

  &lt;!-- "uncustomized" (defined, not custom) -->
  &lt;p>&lt;/p>
  &lt;asdf>&lt;/asdf>

  &lt;!-- "custom" (defined, custom) -->
  &lt;sw-rey>&lt;/sw-rey>
  &lt;p is="sw-finn">&lt;/p>
 </code></pre>
</div>

<p><a for=/>Elements</a> also have an associated
<dfn export id=concept-element-shadow-root for=Element>shadow root</dfn> (null or a
<a for=/>shadow root</a>). It is null unless otherwise stated. An <a for=/>element</a> is a
<dfn export for=Element>shadow host</dfn> if its <a for=Element>shadow root</a> is non-null.

<p>An <a for=/>element</a>'s
<dfn export id=concept-element-qualified-name for=Element>qualified name</dfn> is its
<a for=Element>local name</a> if its <a for=Element>namespace prefix</a> is null, and its
<a for=Element>namespace prefix</a>, followed by "<code>:</code>", followed by its
<a for=Element>local name</a>, otherwise.

<p>An <a for=/>element</a>'s <dfn for=Element>HTML-uppercased qualified name</dfn> is the return
value of these steps:

<ol>
 <li><p>Let <var>qualifiedName</var> be <a>context object</a>'s <a for=Element>qualified name</a>.

 <li><p>If the <a>context object</a> is in the <a>HTML namespace</a> and its
 <a for=Node>node document</a> is an <a>HTML document</a>, then set <var>qualifiedName</var> to
 <var>qualifiedName</var> in <a>ASCII uppercase</a>.

 <li>Return <var>qualifiedName</var>.
</ol>

<p class=note>User agents could optimize <a for=Element>qualified name</a> and
<a for=Element>HTML-uppercased qualified name</a> by storing them in internal slots.

<p>To
<dfn export id=concept-create-element lt="create an element|creating an element">create an element</dfn>,
given a <var>document</var>, <var>localName</var>, <var>namespace</var>, and optional
<var>prefix</var>, <var>is</var>, and <var>synchronous custom elements flag</var>, run these steps:

<ol>
 <li><p>If <var>prefix</var> was not given, let <var>prefix</var> be null.

 <li><p>If <var>is</var> was not given, let <var>is</var> be null.

 <li><p>Let <var>result</var> be null.

 <li><p>Let <var>definition</var> be the result of
 <a lt="look up a custom element definition">looking up a custom element definition</a> given
 <var>document</var>, <var>namespace</var>, <var>localName</var>, and <var>is</var>.

 <li>
  <p>If <var>definition</var> is non-null, and <var>definition</var>'s
  <a for="custom element definition">name</a> is not equal to its
  <a for="custom element definition">local name</a> (i.e., <var>definition</var> represents a
  <a>customized built-in element</a>), then:

  <ol>
   <li><p>Let <var>interface</var> be the <a>element interface</a> for <var>localName</var> and the
   <a>HTML namespace</a>.

   <li><p>Set <var>result</var> to a new <a for=/>element</a> that implements <var>interface</var>,
   with no attributes, <a for=Element>namespace</a> set to the <a>HTML namespace</a>,
   <a for=Element>namespace prefix</a> set to <var>prefix</var>, <a for=Element>local name</a> set
   to <var>localName</var>, <a for=Element>custom element state</a> set to "<code>undefined</code>",
   <a for=Element>custom element definition</a> set to null,
   <a for=Element><code>is</code> value</a> set to <var>is</var>, and <a for=Node>node document</a> set to
   <var>document</var>.

   <li><p>If the <var>synchronous custom elements flag</var> is set,
   <a lt="upgrade an element">upgrade</a> <var>element</var> using <var>definition</var>.

   <li><p>Otherwise, <a>enqueue a custom element upgrade reaction</a> given <var>result</var> and
   <var>definition</var>.
  </ol>
 </li>

 <li>
  <p>Otherwise, if <var>definition</var> is non-null, then:

  <ol>
   <li>
    <p>If the <var>synchronous custom elements flag</var> is set, then run these steps while
    catching any exceptions:

    <ol>
     <li><p>Let <var>C</var> be <var>definition</var>'s
     <a for="custom element definition">constructor</a>.

     <li><p>Set <var>result</var> to the result of <a>constructing</a> <var>C</var>, with no
     arguments.

     <li><p>Assert: <var>result</var>'s <a for=Element>custom element state</a> and
     <a for=Element>custom element definition</a> are initialized.

     <li>
      <p>Assert: <var>result</var>'s <a for=Element>namespace</a> is the <a>HTML namespace</a>.

      <p class=note>IDL enforces that <var>result</var> is an {{HTMLElement}} object, which all use
      the <a>HTML namespace</a>.

     <li><p>If <var>result</var>'s <a for=Element>attribute list</a> <a for=list>is not empty</a>,
     then <a>throw</a> a "{{NotSupportedError!!exception}}" {{DOMException}}.

     <li><p>If <var>result</var> has <a>children</a>, then <a>throw</a> a
     "{{NotSupportedError!!exception}}" {{DOMException}}.

     <li><p>If <var>result</var>'s <a for=tree>parent</a> is not null, then <a>throw</a> a
     "{{NotSupportedError!!exception}}" {{DOMException}}.

     <li><p>If <var>result</var>'s <a for=Node>node document</a> is not <var>document</var>, then
     <a>throw</a> a "{{NotSupportedError!!exception}}" {{DOMException}}.

     <li><p>If <var>result</var>'s <a for=Element>local name</a> is not equal to
     <var>localName</var>, then <a>throw</a> a "{{NotSupportedError!!exception}}" {{DOMException}}.

     <li><p>Set <var>result</var>'s <a for=Element>namespace prefix</a> to <var>prefix</var>.

     <li><p>Set <var>result</var>'s <a for=Element><code>is</code> value</a> to null.
    </ol>

    <p>If any of these steps threw an exception, then:</p>

    <ol>
     <li><p><a>Report the exception</a>.

     <li><p>Set <var>result</var> to a new <a for=/>element</a> that implements the
     {{HTMLUnknownElement}} interface, with no attributes, <a for=Element>namespace</a> set to the
     <a>HTML namespace</a>, <a for=Element>namespace prefix</a> set to <var>prefix</var>,
     <a for=Element>local name</a> set to <var>localName</var>,
     <a for=Element>custom element state</a> set to "<code>failed</code>",
     <a for=Element>custom element definition</a> set to null,
     <a for=Element><code>is</code> value</a> set to null, and <a for=Node>node document</a> set to
     <var>document</var>.
    </ol>
   </li>

   <li>
    <p>Otherwise:

    <ol>
     <li><p>Set <var>result</var> to a new <a for=/>element</a> that implements the {{HTMLElement}}
     interface, with no attributes, <a for=Element>namespace</a> set to the <a>HTML namespace</a>,
     <a for=Element>namespace prefix</a> set to <var>prefix</var>, <a for=Element>local name</a> set
     to <var>localName</var>, <a for=Element>custom element state</a> set to
     "<code>undefined</code>", <a for=Element>custom element definition</a> set to null,
     <a for=Element><code>is</code> value</a> set to null, and <a for=Node>node document</a> set to
     <var>document</var>.

     <li><p><a>Enqueue a custom element upgrade reaction</a> given <var>result</var> and
     <var>definition</var>.
    </ol>
   </li>
  </ol>
 </li>

 <li>
  <p>Otherwise:

  <ol>
   <li><p>Let <var>interface</var> be the <a>element interface</a> for <var>localName</var> and
   <var>namespace</var>.

   <li><p>Set <var>result</var> to a new <a for=/>element</a> that implements <var>interface</var>,
   with no attributes, <a for=Element>namespace</a> set to <var>namespace</var>,
   <a for=Element>namespace prefix</a> set to <var>prefix</var>, <a for=Element>local name</a> set
   to <var>localName</var>, <a for=Element>custom element state</a> set to
   "<code>uncustomized</code>", <a for=Element>custom element definition</a> set to null,
   <a for=Element><code>is</code> value</a> set to <var>is</var>, and <a for=Node>node document</a> set to
   <var>document</var>.

   <li><p>If <var>namespace</var> is the <a>HTML namespace</a>, and either <var>localName</var> is a
   <a>valid custom element name</a> or <var>is</var> is non-null, then set <var>result</var>'s
   <a for=Element>custom element state</a> to "<code>undefined</code>".
  </ol>
 </li>

 <li><p>Return <var>result</var>.
</ol>

<p><a for=/>Elements</a> also have an
<dfn export id=concept-element-attribute for=Element>attribute list</dfn>, which is a <a>list</a>
exposed through a {{NamedNodeMap}}. Unless explicitly given when an <a for=/>element</a> is created,
its <a for=Element>attribute list</a> <a for=list>is empty</a>.

<p>An <a for="/">element</a>
<dfn export id=concept-element-attribute-has lt="has an attribute">has</dfn> an <a>attribute</a>
<var>A</var> if its <a for=Element>attribute list</a> <a for=list>contains</a> <var>A</var>.

<p>This and <a lt="other applicable specifications">other specifications</a> may define
<dfn export id=concept-element-attributes-change-ext>attribute change steps</dfn> for
<a for=/>elements</a>. The algorithm is passed <var>element</var>, <var>localName</var>,
<var>oldValue</var>, <var>value</var>, and <var>namespace</var>.

<p>To <dfn noexport>handle attribute changes</dfn> for an <a>attribute</a> <var>attribute</var> with
<var>element</var>, <var>oldValue</var>, and <var>newValue</var>, run these steps:

<ol>
 <li><p><a>Queue a mutation record</a> of "<code>attributes</code>" for <var>element</var> with
 <var>attribute</var>'s <a for=Attr>local name</a>, <var>attribute</var>'s
 <a for=Attr>namespace</a>, <var>oldValue</var>, « », « », null, and null.

 <li><p>If <var>element</var> is <a for=Element>custom</a>, then
 <a>enqueue a custom element callback reaction</a> with <var>element</var>, callback name
 "<code>attributeChangedCallback</code>", and an argument list containing <var>attribute</var>'s
 <a for=Attr>local name</a>, <var>oldValue</var>, <var>newValue</var>, and <var>attribute</var>'s
 <a for=Attr>namespace</a>.

 <li><p>Run the <a>attribute change steps</a> with <var>element</var>, <var>attribute</var>'s
 <a for=Attr>local name</a>, <var>oldValue</var>, <var>newValue</var>, and <var>attribute</var>'s
 <a for=Attr>namespace</a>.
</ol>

<p>To <dfn export id=concept-element-attributes-change lt="change an attribute">change</dfn> an
<a>attribute</a> <var>attribute</var> to <var>value</var>, run these steps:

<ol>
 <li><p><a>Handle attribute changes</a> for <var>attribute</var> with <var>attribute</var>'s
 <a for=Attr>element</a>, <var>attribute</var>'s <a for=Attr>value</a>, and <var>value</var>.

 <li><p>Set <var>attribute</var>'s <a for=Attr>value</a> to <var>value</var>.
</ol>

<p>To <dfn export id=concept-element-attributes-append lt="append an attribute">append</dfn> an
<a>attribute</a> <var>attribute</var> to an <a for="/">element</a> <var>element</var>, run these
steps:

<ol>
 <li><p><a>Handle attribute changes</a> for <var>attribute</var> with <var>element</var>, null, and
 <var>attribute</var>'s <a for=Attr>value</a>.

 <li><p><a for=list>Append</a> <var>attribute</var> to <var>element</var>'s
 <a for=Element>attribute list</a>.

 <li><p>Set <var>attribute</var>'s <a for=Attr>element</a> to <var>element</var>.
</ol>

<p>To <dfn export id=concept-element-attributes-remove lt="remove an attribute">remove</dfn> an
<a>attribute</a> <var>attribute</var>, run these steps:

<ol>
 <li><p><a>Handle attribute changes</a> for <var>attribute</var> with <var>attribute</var>'s
 <a for=Attr>element</a>, <var>attribute</var>'s <a for=Attr>value</a>, and null.

 <li><a for=list>Remove</a> <var>attribute</var> from <var>attribute</var>'s
 <a for=Attr>element</a>'s <a for=Element>attribute list</a>.

 <li><p>Set <var>attribute</var>'s <a for=Attr>element</a> to null.
</ol>

<p>To <dfn export id=concept-element-attributes-replace lt="replace an attribute">replace</dfn> an
<a>attribute</a> <var>oldAttr</var> with an <a>attribute</a> <var>newAttr</var>, run these steps:

<ol>
 <li><p><a>Handle attribute changes</a> for <var>oldAttr</var> with <var>oldAttr</var>'s
 <a for=Attr>element</a>, <var>oldAttr</var>'s <a for=Attr>value</a>, and <var>newAttr</var>'s
 <a for=Attr>value</a>.

 <li><p><a for=list>Replace</a> <var>oldAttr</var> by <var>newAttr</var> in <var>oldAttr</var>'s
 <a for=Attr>element</a>'s <a for=Element>attribute list</a>.

 <li><p>Set <var>newAttr</var>'s <a for=Attr>element</a> to <var>oldAttr</var>'s
 <a for=Attr>element</a>.

 <li><p>Set <var>oldAttr</var>'s <a for=Attr>element</a> to null.
</ol>

<hr>

<p>To <dfn export id=concept-element-attributes-get-by-name>get an attribute by name</dfn> given a
<var>qualifiedName</var> and <a for="/">element</a> <var>element</var>, run these steps:

<ol>
 <li><p>If <var>element</var> is in the <a>HTML namespace</a> and its <a for=Node>node document</a>
 is an <a>HTML document</a>, then set <var>qualifiedName</var> to <var>qualifiedName</var> in
 <a>ASCII lowercase</a>.

 <li><p>Return the first <a>attribute</a> in <var>element</var>'s <a for=Element>attribute list</a>
 whose <a for=Attr>qualified name</a> is <var>qualifiedName</var>, and null otherwise.
</ol>

<p>To
<dfn export id=concept-element-attributes-get-by-namespace>get an attribute by namespace and local name</dfn>
given a <var>namespace</var>, <var>localName</var>, and <a for="/">element</a> <var>element</var>,
run these steps:

<ol>
 <li>If <var>namespace</var> is the empty string, set it to null.

 <li>Return the <a>attribute</a> in
 <var>element</var>'s <a for=Element>attribute list</a>
 whose <a for="Attr">namespace</a> is
 <var>namespace</var> and
 <a for="Attr">local name</a> is
 <var>localName</var>, if any, and null otherwise.
</ol>

<p>To <dfn export id=concept-element-attributes-get-value>get an attribute value</dfn> given an
<a for=/>element</a> <var>element</var>, <var>localName</var>, and optionally a <var>namespace</var>
(null unless stated otherwise), run these steps:</p>

<ol>
 <li><p>Let <var>attr</var> be the result of
 <a lt="get an attribute by namespace and local name">getting an attribute</a> given
 <var>namespace</var>, <var>localName</var>, and <var>element</var>.</p></li>

 <li><p>If <var>attr</var> is null, then return the empty string.</p></li>

 <li><p>Return <var>attr</var>'s <a for=Attr>value</a>.</p></li>
</ol>

<p>To <dfn export id=concept-element-attributes-set>set an attribute</dfn> given an
<var>attr</var> and <var>element</var>, run these steps:

<ol>
 <li><p>If <var>attr</var>'s <a for=Attr>element</a> is neither null nor <var>element</var>,
 <a>throw</a> an "{{InUseAttributeError!!exception}}" {{DOMException}}.

 <li><p>Let <var>oldAttr</var> be the result of
 <a lt="get an attribute by namespace and local name">getting an attribute</a> given
 <var>attr</var>'s <a for="Attr">namespace</a>, <var>attr</var>'s <a for="Attr">local name</a>, and
 <var>element</var>.

 <li><p>If <var>oldAttr</var> is <var>attr</var>, return <var>attr</var>.

 <li><p>If <var>oldAttr</var> is non-null, then <a lt="replace an attribute">replace</a>
 <var>oldAttr</var> with <var>attr</var>.

 <li><p>Otherwise, <a lt="append an attribute">append</a> <var>attr</var> to <var>element</var>.

 <li><p>Return <var>oldAttr</var>.
</ol>

<p>To <dfn export id=concept-element-attributes-set-value>set an attribute value</dfn> for an
<a for="/">element</a> <var>element</var>, using a <var>localName</var> and <var>value</var>, and an
optional <var>prefix</var>, and <var>namespace</var>, run these steps:

<ol>
 <li>If <var>prefix</var> is not given, set it to null.

 <li>If <var>namespace</var> is not given, set it to null.

 <li>Let <var>attribute</var> be the result of
 <a lt="get an attribute by namespace and local name">getting an attribute</a> given
 <var>namespace</var>, <var>localName</var>, and <var>element</var>.

 <li>If <var>attribute</var> is null, create an <a>attribute</a> whose <a for=Attr>namespace</a> is
 <var>namespace</var>, <a for=Attr>namespace prefix</a> is <var>prefix</var>,
 <a for=Attr>local name</a> is <var>localName</var>, <a for=Attr>value</a> is <var>value</var>, and
 <a for=Node>node document</a> is <var>element</var>'s <a for=Node>node document</a>, then
 <a lt="append an attribute">append</a> this <a>attribute</a> to <var>element</var>, and then
 return.

 <li><p><a lt="change an attribute">Change</a> <var>attribute</var> to <var>value</var>.
</ol>

<p>To <dfn export id=concept-element-attributes-remove-by-name>remove an attribute by name</dfn>
given a <var>qualifiedName</var> and <a for="/">element</a> <var>element</var>, run these steps:

<ol>
 <li><p>Let <var>attr</var> be the result of
 <a lt="get an attribute by name">getting an attribute</a> given <var>qualifiedName</var> and
 <var>element</var>.

 <li><p>If <var>attr</var> is non-null, then <a lt="remove an attribute">remove</a> <var>attr</var>.

 <li><p>Return <var>attr</var>.
</ol>

<p>To
<dfn export id=concept-element-attributes-remove-by-namespace>remove an attribute by namespace and local name</dfn>
given a <var>namespace</var>, <var>localName</var>, and <a for="/">element</a> <var>element</var>,
run these steps:

<ol>
 <li><p>Let <var>attr</var> be the result of
 <a lt="get an attribute by namespace and local name">getting an attribute</a> given
 <var>namespace</var>, <var>localName</var>, and <var>element</var>.

 <li><p>If <var>attr</var> is non-null, then <a lt="remove an attribute">remove</a> <var>attr</var>.

 <li><p>Return <var>attr</var>.
</ol>

<hr>

<p>An <a for=/>element</a> can have an associated
<dfn export for=Element id=concept-id lt="ID">unique identifier (ID)</dfn>

<p class=note>Historically <a for="/">elements</a> could have multiple identifiers e.g., by using
the HTML <code>id</code> <a>attribute</a> and a DTD. This specification makes <a for=Element>ID</a>
a concept of the DOM and allows for only one per <a for="/">element</a>, given by an
<a lt="named attribute"><code>id</code> attribute</a>.

<p>Use these <a>attribute change steps</a> to update an <a for=/>element</a>'s
<a for=Element>ID</a>:

<ol>
 <li><p>If <var>localName</var> is <code>id</code>, <var>namespace</var> is null, and
 <var>value</var> is null or the empty string, then unset <var>element</var>'s
 <a for=Element>ID</a>.

 <li><p>Otherwise, if <var>localName</var> is <code>id</code>, <var>namespace</var> is null, then
 set <var>element</var>'s <a for=Element>ID</a> to <var>value</var>.
</ol>

<p class="note no-backref">While this specification defines requirements for <code>class</code>,
<code>id</code>, and <code>slot</code> <a>attributes</a> on any <a for="/">element</a>, it makes no
claims as to whether using them is conforming or not.

<hr>

A <a>node</a>'s
<a for=tree>parent</a> of type
{{Element}} is known as a <dfn export>parent element</dfn>. If the
<a>node</a> has a
<a for=tree>parent</a> of a different type, its
<a>parent element</a> is null.

<hr>

<dl class=domintro>
 <dt><var>namespace</var> = <var>element</var> . {{Element/namespaceURI}}
 <dd>Returns the <a for=Element>namespace</a>.

 <dt><var>prefix</var> = <var>element</var> . {{Element/prefix}}
 <dd>Returns the
 <a for=Element>namespace prefix</a>.

 <dt><var>localName</var> = <var>element</var> . {{Element/localName}}
 <dd>Returns the
 <a for=Element>local name</a>.

 <dt><var>qualifiedName</var> = <var>element</var> . {{Element/tagName}}
 <dd>Returns the <a for=Element>HTML-uppercased qualified name</a>.
</dl>

<p>The <dfn attribute for=Element><code>namespaceURI</code></dfn> attribute's getter must return
the <a>context object</a>'s <a for=Element>namespace</a>.

<p>The <dfn attribute for=Element><code>prefix</code></dfn> attribute's getter must return the
<a>context object</a>'s <a for=Element>namespace prefix</a>.

<p>The <dfn attribute for=Element><code>localName</code></dfn> attribute's getter must return the
<a>context object</a>'s <a for=Element>local name</a>.

<p>The <dfn attribute for=Element><code>tagName</code></dfn> attribute's getter must return the
<a>context object</a>'s <a for=Element>HTML-uppercased qualified name</a>.

<hr>

<dl class=domintro>
 <dt><code><var>element</var> . <a attribute for=Element>id</a> [ = <var>value</var> ]</code>
 <dd><p>Returns the value of <var>element</var>'s <code>id</code> content attribute. Can be set to
 change it.

 <dt><code><var>element</var> . <a attribute for=Element>className</a> [ = <var>value</var> ]</code>
 <dd><p>Returns the value of <var>element</var>'s <code>class</code> content attribute. Can be set
 to change it.

 <dt><code><var>element</var> . <a attribute for=Element>classList</a></code>
 <dd><p>Allows for manipulation of <var>element</var>'s <code>class</code> content attribute as a
 set of whitespace-separated tokens through a {{DOMTokenList}} object.

 <dt><code><var>element</var> . <a attribute for=Element>slot</a> [ = <var>value</var> ]</code>
 <dd><p>Returns the value of <var>element</var>'s <code>slot</code> content attribute. Can be set to
 change it.
</dl>

<p>IDL attributes that are defined to <dfn export for=Attr id=concept-reflect>reflect</dfn> a
content <a>attribute</a> of a given <var>name</var>, must have a getter and setter that follow these
steps:</p>

<dl>
 <dt>getter
 <dd><p>Return the result of running <a>get an attribute value</a> given <a>context object</a> and
 <var>name</var>.</p></dd>

 <dt>setter
 <dd><p><a>Set an attribute value</a> for the <a>context object</a> using <var>name</var> and the
 given value.</p></dd>
</dl>

<p>The <dfn attribute for=Element><code>id</code></dfn> attribute must <a for=Attr>reflect</a> the
"<code>id</code>" content attribute.

<p>The <dfn attribute for=Element><code>className</code></dfn> attribute must
<a for=Attr>reflect</a> the "<code>class</code>" content attribute.

<p>The <dfn attribute for=Element><code>classList</code></dfn> attribute's getter must return a
{{DOMTokenList}} object whose associated <a for=/>element</a> is the <a>context object</a> and whose
associated <a>attribute</a>'s <a for=Attr>local name</a> is <code>class</code>. The <a>token set</a>
of this particular {{DOMTokenList}} object are also known as the <a for="/">element</a>'s
<dfn export for=Element id=concept-class lt="class">classes</dfn>.

<p>The <dfn attribute for=Element><code>slot</code></dfn> attribute must <a for=Attr>reflect</a> the
"<code>slot</code>" content attribute.

<p class="note"><code>id</code>, <code>class</code>, and <code>slot</code> are effectively
superglobal attributes as they can appear on any element, regardless of that element's
namespace.</p>

<hr>

<dl class=domintro>
 <dt><code><var>element</var> . <a method for=Element lt=hasAttributes()>hasAttributes</a>()</code>
 <dd><p>Returns true if <var>element</var> has attributes, and false otherwise.

 <dt><code><var>element</var> . <a method for=Element lt=getAttributeNames()>getAttributeNames</a>()</code>
 <dd><p>Returns the <a for=Attr>qualified names</a> of all <var>element</var>'s <a>attributes</a>.
 Can contain duplicates.

 <dt><code><var>element</var> . <a method for=Element lt=getAttribute()>getAttribute</a>(<var>qualifiedName</var>)</code>
 <dd><p>Returns <var>element</var>'s first <a>attribute</a> whose <a for=Attr>qualified name</a> is
 <var>qualifiedName</var>, and null if there is no such <a>attribute</a> otherwise.

 <dt><code><var>element</var> . <a method for=Element lt=getAttributeNS()>getAttributeNS</a>(<var>namespace</var>, <var>localName</var>)</code>
 <dd><p>Returns <var>element</var>'s <a>attribute</a> whose <a for=Attr>namespace</a> is
 <var>namespace</var> and <a for=Attr>local name</a> is <var>localName</var>, and null if there is
 no such <a>attribute</a> otherwise.

 <dt><code><var>element</var> . <a method for=Element lt=setAttribute()>setAttribute</a>(<var>qualifiedName</var>, <var>value</var>)</code>
 <dd><p>Sets the <a for=Attr>value</a> of <var>element</var>'s first <a>attribute</a> whose
 <a for=Attr>qualified name</a> is <var>qualifiedName</var> to <var>value</var>.

 <dt><code><var>element</var> . <a method for=Element lt=setAttributeNS()>setAttributeNS</a>(<var>namespace</var>, <var>localName</var>, <var>value</var>)</code>
 <dd><p>Sets the <a for=Attr>value</a> of <var>element</var>'s <a>attribute</a> whose
 <a for=Attr>namespace</a> is <var>namespace</var> and <a for=Attr>local name</a> is
 <var>localName</var> to <var>value</var>.

 <dt><code><var>element</var> . <a method for=Element lt=removeAttribute()>removeAttribute</a>(<var>qualifiedName</var>)</code>
 <dd><p>Removes <var>element</var>'s first <a>attribute</a> whose <a for=Attr>qualified name</a> is
 <var>qualifiedName</var>.

 <dt><code><var>element</var> . <a method for=Element lt=removeAttributeNS()>removeAttributeNS</a>(<var>namespace</var>, <var>localName</var>)</code>
 <dd><p>Removes <var>element</var>'s <a>attribute</a> whose <a for=Attr>namespace</a> is
 <var>namespace</var> and <a for=Attr>local name</a> is <var>localName</var>.

 <dt><code><var>element</var> . <a method for=Element lt=toggleAttribute()>toggleAttribute</a>(<var>qualifiedName</var> [, <var>force</var>])</code>
 <dd>
  <p>If <var>force</var> is not given, "toggles" <var>qualifiedName</var>, removing it if it is
  present and adding it if it is not present. If <var>force</var> is true, adds
  <var>qualifiedName</var>. If <var>force</var> is false, removes <var>qualifiedName</var>.

  <p>Returns true if <var>qualifiedName</var> is now present, and false otherwise.

 <dt><code><var>element</var> . <a method for=Element lt=hasAttribute()>hasAttribute</a>(<var>qualifiedName</var>)</code>
 <dd><p>Returns true if <var>element</var> has an <a>attribute</a> whose
 <a for=Attr>qualified name</a> is <var>qualifiedName</var>, and false otherwise.

 <dt><code><var>element</var> . <a method for=Element lt=hasAttributeNS()>hasAttributeNS</a>(<var>namespace</var>, <var>localName</var>)</code>
 <dd><p>Returns true if <var>element</var> has an <a>attribute</a> whose <a for=Attr>namespace</a>
 is <var>namespace</var> and <a for=Attr>local name</a> is <var>localName</var>.
</dl>

<p>The <dfn method for=Element><code>hasAttributes()</code></dfn> method, when invoked, must return
false if <a>context object</a>'s <a for=Element>attribute list</a> <a for=list>is empty</a>, and
true otherwise.

<p>The <dfn attribute for=Element><code>attributes</code></dfn> attribute's getter must return the
associated {{NamedNodeMap}}.

<p>The <dfn method for=Element><code>getAttributeNames()</code></dfn> method, when invoked, must
return the <a for=Attr>qualified names</a> of the <a>attributes</a> in <a>context object</a>'s
<a for=Element>attribute list</a>, in order, and a new <a>list</a> otherwise.

<p class=note>These are not guaranteed to be unique.<!-- A theoretical getAttributeNamesNS() could
return an array of unique two-value-arrays. -->

<p>The <dfn method for=Element><code>getAttribute(<var>qualifiedName</var>)</code></dfn> method,
when invoked, must run these steps:

<ol>
 <li><p>Let <var>attr</var> be the result of
 <a lt="get an attribute by name">getting an attribute</a> given <var>qualifiedName</var> and the
 <a>context object</a>.

 <li><p>If <var>attr</var> is null, return null.

 <li><p>Return <var>attr</var>'s <a for=Attr>value</a>.
</ol>

<p>The
<dfn method for=Element><code>getAttributeNS(<var>namespace</var>, <var>localName</var>)</code></dfn>
method, when invoked, must these steps:

<ol>
 <li><p>Let <var>attr</var> be the result of
 <a lt="get an attribute by namespace and local name">getting an attribute</a> given
 <var>namespace</var>, <var>localName</var>, and the <a>context object</a>.

 <li><p>If <var>attr</var> is null, return null.

 <li><p>Return <var>attr</var>'s <a for=Attr>value</a>.
</ol>

<p>The
<dfn method for=Element><code>setAttribute(<var>qualifiedName</var>, <var>value</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li><p>If <var>qualifiedName</var> does not match the <code><a type>Name</a></code> production in
 XML, then <a>throw</a> an "{{InvalidCharacterError!!exception}}" {{DOMException}}.

 <li><p>If the <a>context object</a> is in the <a>HTML namespace</a> and its
 <a for=Node>node document</a> is an <a>HTML document</a>, then set <var>qualifiedName</var> to
 <var>qualifiedName</var> in <a>ASCII lowercase</a>.

 <li><p>Let <var>attribute</var> be the first <a>attribute</a> in <a>context object</a>'s
 <a for=Element>attribute list</a> whose <a for=Attr>qualified name</a> is <var>qualifiedName</var>,
 and null otherwise.
 <!-- This is step 2 of "get an attribute by name", modified as appropriate -->

 <li><p>If <var>attribute</var> is null, create an <a>attribute</a> whose
 <a for="Attr">local name</a> is <var>qualifiedName</var>, <a for=Attr>value</a> is
 <var>value</var>, and <a for=Node>node document</a> is <a>context object</a>'s
 <a for=Node>node document</a>, then <a lt="append an attribute">append</a> this <a>attribute</a> to
 <a>context object</a>, and then return.

 <li><p><a lt="change an attribute">Change</a> <var>attribute</var> to <var>value</var>.
</ol>

<p>The
<dfn method for=Element><code>setAttributeNS(<var>namespace</var>, <var>qualifiedName</var>, <var>value</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li><p>Let <var>namespace</var>, <var>prefix</var>, and <var>localName</var> be the result of
 passing <var>namespace</var> and <var>qualifiedName</var> to <a>validate and extract</a>.

 <li><p><a>Set an attribute value</a> for the <a>context object</a> using <var>localName</var>,
 <var>value</var>, and also <var>prefix</var> and <var>namespace</var>.
</ol>

<p>The
<dfn method for=Element><code>removeAttribute(<var>qualifiedName</var>)</code></dfn>
method, when invoked, must <a lt="remove an attribute by name">remove an attribute</a> given
<var>qualifiedName</var> and the <a>context object</a>, and then return undefined.

<p>The
<dfn method for=Element><code>removeAttributeNS(<var>namespace</var>, <var>localName</var>)</code></dfn>
method, when invoked, must
<a lt="remove an attribute by namespace and local name">remove an attribute</a> given
<var>namespace</var>, <var>localName</var>, and <a>context object</a>, and then return undefined.

<p>The <dfn method for=Element><code>hasAttribute(<var>qualifiedName</var>)</code></dfn> method,
when invoked, must run these steps:

<ol>
 <li><p>If the <a>context object</a> is in the <a>HTML namespace</a> and its
 <a for=Node>node document</a> is an <a>HTML document</a>, then set <var>qualifiedName</var> to
 <var>qualifiedName</var> in <a>ASCII lowercase</a>.

 <li><p>Return true if the <a>context object</a> <a lt="has an attribute">has</a> an
 <a>attribute</a> whose <a for=Attr>qualified name</a> is <var>qualifiedName</var>, and false
 otherwise.
</ol>

<p>The <dfn method for=Element><code>toggleAttribute(<var>qualifiedName</var>, <var>force</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li><p>If <var>qualifiedName</var> does not match the <code><a type>Name</a></code> production in
 XML, then <a>throw</a> an "{{InvalidCharacterError!!exception}}" {{DOMException}}.

 <li><p>If the <a>context object</a> is in the <a>HTML namespace</a> and its
 <a for=Node>node document</a> is an <a>HTML document</a>, then set <var>qualifiedName</var> to
 <var>qualifiedName</var> in <a>ASCII lowercase</a>.

 <li><p>Let <var>attribute</var> be the first <a>attribute</a> in the <a>context object</a>'s
 <a for=Element>attribute list</a> whose <a for=Attr>qualified name</a> is <var>qualifiedName</var>,
 and null otherwise.
 <!-- This is step 2 of "get an attribute by name", modified as appropriate -->

 <li>
  <p>If <var>attribute</var> is null, then:

  <ol>
   <li><p>If <var>force</var> is not given or is true, create an <a>attribute</a> whose
   <a for="Attr">local name</a> is <var>qualifiedName</var>, <a for=Attr>value</a> is the empty
   string, and <a for=Node>node document</a> is the <a>context object</a>'s
   <a for=Node>node document</a>, then <a lt="append an attribute">append</a> this <a>attribute</a>
   to the <a>context object</a>, and then return true.

   <li><p>Return false.
  </ol>

 <li><p>Otherwise, if <var>force</var> is not given or is false,
 <a lt="remove an attribute by name">remove an attribute</a> given <var>qualifiedName</var> and the
 <a>context object</a>, and then return false.

 <li><p>Return true.
</ol>

<p>The
<dfn method for=Element><code>hasAttributeNS(<var>namespace</var>, <var>localName</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li>If <var>namespace</var> is the empty string, set it to null.

 <li>Return true if the <a>context object</a>
 <a lt="has an attribute">has</a> an
 <a>attribute</a> whose
 <a for="Attr">namespace</a> is <var>namespace</var>
 and <a for="Attr">local name</a> is
 <var>localName</var>, and false otherwise.
</ol>

<hr>

<p>The <dfn method for=Element><code>getAttributeNode(<var>qualifiedName</var>)</code></dfn>
method, when invoked, must return the result of
<a lt="get an attribute by name">getting an attribute</a> given <var>qualifiedName</var> and
<a>context object</a>.

<p>The
<dfn method for=Element><code>getAttributeNodeNS(<var>namespace</var>, <var>localName</var>)</code></dfn>
method, when invoked, must return the result of
<a lt="get an attribute by namespace and local name">getting an attribute</a> given
<var>namespace</var>, <var>localName</var>, and the <a>context object</a>.

<p>The <dfn method for=Element><code>setAttributeNode(<var>attr</var>)</code></dfn> and
<dfn method for=Element><code>setAttributeNodeNS(<var>attr</var>)</code></dfn> methods, when
invoked, must return the result of <a lt="set an attribute">setting an attribute</a> given
<var>attr</var> and the <a>context object</a>.

<p>The <dfn method for=Element><code>removeAttributeNode(<var>attr</var>)</code></dfn> method,
when invoked, must run these steps:

<ol>
 <li><p>If <a>context object</a>'s <a for=Element>attribute list</a> does not
 <a for=list>contain</a> <var>attr</var>, then <a>throw</a> a "{{NotFoundError!!exception}}"
 {{DOMException}}.

 <li><p><a lt="remove an attribute">Remove</a> <var>attr</var>.

 <li><p>Return <var>attr</var>.
</ol>

<hr>

<dl class=domintro>
 <dt><code>var shadow = <var>element</var> . {{attachShadow(init)}}</code>
 <dd><p>Creates a <a for=/>shadow root</a> for <var>element</var> and returns it.

 <dt><code>var shadow = <var>element</var> . {{shadowRoot}}</code>
 <dd><p>Returns <var>element</var>'s <a for=Element>shadow root</a>, if any, and if
 <a for=/>shadow root</a>'s <a for=ShadowRoot>mode</a> is "<code>open</code>", and null otherwise.
</dl>

<p>The <dfn method for=Element><code>attachShadow(<var>init</var>)</code></dfn> method, when
invoked, must run these steps:

<ol>
 <li><p>If <a>context object</a>'s <a for=Element>namespace</a> is <em>not</em> the
 <a>HTML namespace</a>, then <a>throw</a> a "{{NotSupportedError!!exception}}" {{DOMException}}.

 <li><p>If <a>context object</a>'s <a for=Element>local name</a> is <em>not</em> a
 <a>valid custom element name</a>,
 "<code>article</code>",
 "<code>aside</code>",
 "<code>blockquote</code>",
 "<code>body</code>",
 "<code>div</code>",
 "<code>footer</code>",
 "<code>h1</code>",
 "<code>h2</code>",
 "<code>h3</code>",
 "<code>h4</code>",
 "<code>h5</code>",
 "<code>h6</code>",
 "<code>header</code>",
 "<code>main</code>",
 "<code>nav</code>",
 "<code>p</code>",
 "<code>section</code>", or
 "<code>span</code>", then <a>throw</a> a "{{NotSupportedError!!exception}}" {{DOMException}}.

 <li>
  <p>If <a>context object</a>'s <a for=Element>local name</a> is a
  <a>valid custom element name</a>, or <a>context object</a>'s
  <a for=Element><code>is</code> value</a> is not null, then:

  <ol>
   <li><p>Let <var>definition</var> be the result of
   <a lt="look up a custom element definition">looking up a custom element definition</a> given
   <a>context object</a>'s <a for=Node>node document</a>, its <a for=Element>namespace</a>, its
   <a for=Element>local name</a>, and its <a for=Element><code>is</code> value</a>.

   <li><p>If <var>definition</var> is not null and <var>definition</var>'s
   <a for="custom element definition">disable shadow</a> is true, then <a>throw</a> a
   "{{NotSupportedError!!exception}}" {{DOMException}}.
  </ol>
 </li>

 <li><p>If <a>context object</a> is a <a for=Element>shadow host</a>, then <a>throw</a> an
 "{{NotSupportedError!!exception}}" {{DOMException}}.

 <li><p>Let <var>shadow</var> be a new <a for=/>shadow root</a> whose <a for=Node>node document</a>
 is <a>context object</a>'s <a for=Node>node document</a>, <a for=DocumentFragment>host</a> is
 <a>context object</a>, and <a for=ShadowRoot>mode</a> is <var>init</var>'s {{ShadowRootInit/mode}}.

 <li><p>Set <var>shadow</var>'s <a for=ShadowRoot>delegates focus</a> to <var>init</var>'s
 {{ShadowRootInit/delegatesFocus}}.

 <li><p>Set <a>context object</a>'s <a for=Element>shadow root</a> to <var>shadow</var>.

 <li><p>Return <var>shadow</var>.
</ol>

<p>The <dfn attribute for=Element><code>shadowRoot</code></dfn> attribute's getter must run these
steps:

<ol>
 <li><p>Let <var>shadow</var> be <a>context object</a>'s <a for=Element>shadow root</a>.

 <li><p>If <var>shadow</var> is null or its <a for=ShadowRoot>mode</a> is "<code>closed</code>",
 then return null.</p></li>

 <li><p>Return <var>shadow</var>.
</ol>

<hr>

<dl class=domintro>
 <dt><code><var>element</var> . {{closest(selectors)}}</code>
 <dd>Returns the first (starting at <var>element</var>)
 <a for=tree>inclusive ancestor</a> that matches
 <var>selectors</var>, and null otherwise.

 <dt><code><var>element</var> . {{matches(selectors)}}</code>
 <dd>Returns true if matching <var>selectors</var> against
 <var>element</var>'s <a for=tree>root</a> yields
 <var>element</var>, and false otherwise.
</dl>

The <dfn method for=Element><code>closest(<var>selectors</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li>Let <var>s</var> be the result of
 <a>parse a selector</a> from <var>selectors</var>.
 [[!SELECTORS4]]

 <li>If <var>s</var> is failure, <a>throw</a> a
 "{{SyntaxError!!exception}}" {{DOMException}}.

 <li>Let <var>elements</var> be <a>context object</a>'s
 <a for=tree>inclusive ancestors</a> that are
 <a for="/">elements</a>, in reverse
 <a>tree order</a>.

 <li>For each <var>element</var> in <var>elements</var>, if
 <a>match a selector against an element</a>, using
 <var>s</var>, <var>element</var>, and
 <a>:scope element</a> <a>context object</a>,
 returns success, return <var>element</var>. [[!SELECTORS4]]

 <li>Return null.
</ol>

The <dfn method for=Element><code>matches(<var>selectors</var>)</code></dfn> and
<dfn method for=Element><code>webkitMatchesSelector(<var>selectors</var>)</code></dfn> methods, when
invoked, must run these steps:

<ol>
 <li>Let <var>s</var> be the result of
 <a>parse a selector</a> from <var>selectors</var>.
 [[!SELECTORS4]]

 <li>If <var>s</var> is failure, <a>throw</a> a
 "{{SyntaxError!!exception}}" {{DOMException}}.

 <li>Return true if the result of
 <a>match a selector against an element</a>, using
 <var>s</var>, <var>element</var>, and
 <a>:scope element</a> <a>context object</a>,
 returns success, and false otherwise. [[!SELECTORS4]]
</ol>

<hr>

<p>The <dfn method for=Element><code>getElementsByTagName(<var>qualifiedName</var>)</code></dfn>
method, when invoked, must return the
<a>list of elements with qualified name <var>qualifiedName</var></a> for <a>context object</a>.

<p>The
<dfn method for=Element><code>getElementsByTagNameNS(<var>namespace</var>, <var>localName</var>)</code></dfn>
method, when invoked, must return the
<a>list of elements with namespace <var>namespace</var> and local name <var>localName</var></a> for
<a>context object</a>.

<p>The <dfn method for=Element><code>getElementsByClassName(<var>classNames</var>)</code></dfn>
method, when invoked, must return the <a>list of elements with class names <var>classNames</var></a>
for <a>context object</a>.

<hr>

<p>To <dfn>insert adjacent</dfn>, given an <a for=/>element</a> <var>element</var>, string
<var>where</var>, and a <a>node</a> <var>node</var>, run the steps associated with the first
<a>ASCII case-insensitive</a> match for <var>where</var>:

<dl class=switch>
 <dt>"<code>beforebegin</code>"
 <dd>
  <p>If <var>element</var>'s <a for=tree>parent</a> is null, return null.

  <p>Return the result of <a>pre-inserting</a> <var>node</var> into <var>element</var>'s
  <a for=tree>parent</a> before <var>element</var>.

 <dt>"<code>afterbegin</code>"
 <dd><p>Return the result of <a>pre-inserting</a> <var>node</var> into <var>element</var> before
 <var>element</var>'s <a for=tree>first child</a>.

 <dt>"<code>beforeend</code>"
 <dd><p>Return the result of <a>pre-inserting</a> <var>node</var> into <var>element</var> before
 null.

 <dt>"<code>afterend</code>"
 <dd>
  <p>If <var>element</var>'s <a for=tree>parent</a> is null, return null.

  <p>Return the result of <a>pre-inserting</a> <var>node</var> into <var>element</var>'s
  <a for=tree>parent</a> before <var>element</var>'s <a for=tree>next sibling</a>.

 <dt>Otherwise</dt>
 <dd><p><a>Throw</a> a "{{SyntaxError!!exception}}" {{DOMException}}.
</dl>

<p>The
<dfn method for=Element><code>insertAdjacentElement(<var>where</var>, <var>element</var>)</code></dfn>
method, when invoked, must return the result of running <a>insert adjacent</a>, given
<a>context object</a>, <var>where</var>, and <var>element</var>.

<p>The
<dfn method for=Element><code>insertAdjacentText(<var>where</var>, <var>data</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li><p>Let <var>text</var> be a new {{Text}} <a>node</a>  whose <a for=CharacterData>data</a> is
 <var>data</var> and <a for=Node>node document</a> is <a>context object</a>'s
 <a for=Node>node document</a>.

 <li><p>Run <a>insert adjacent</a>, given <a>context object</a>, <var>where</var>, and
 <var>text</var>.
</ol>

<p class="note">This method returns nothing because it existed before we had a chance to design it.


<h4 id=interface-namednodemap>Interface {{NamedNodeMap}}</h4>

<pre class=idl>
[Exposed=Window,
 LegacyUnenumerableNamedProperties]
interface NamedNodeMap {
  readonly attribute unsigned long length;
  getter Attr? item(unsigned long index);
  getter Attr? getNamedItem(DOMString qualifiedName);
  Attr? getNamedItemNS(DOMString? namespace, DOMString localName);
  [CEReactions] Attr? setNamedItem(Attr attr);
  [CEReactions] Attr? setNamedItemNS(Attr attr);
  [CEReactions] Attr removeNamedItem(DOMString qualifiedName);
  [CEReactions] Attr removeNamedItemNS(DOMString? namespace, DOMString localName);
};
</pre>

A {{NamedNodeMap}} has an associated
<dfn export id=concept-namednodemap-element for=NamedNodeMap>element</dfn> (an
<a for="/">element</a>).

A {{NamedNodeMap}} object's
<dfn export id=concept-namednodemap-attribute for=NamedNodeMap>attribute list</dfn> is its
<a for=NamedNodeMap>element</a>'s
<a for=Element>attribute list</a>.

<hr>

<p>A {{NamedNodeMap}} object's <a>supported property indices</a> are the numbers in the
range zero to its <a for=NamedNodeMap>attribute list</a>'s <a for=list>size</a> minus one, unless
the <a for=NamedNodeMap>attribute list</a> <a for=list>is empty</a>, in which case there are no
<a>supported property indices</a>.

<p>The <dfn attribute for="NamedNodeMap"><code>length</code></dfn> attribute's getter must return
the <a for=NamedNodeMap>attribute list</a>'s <a for=list>size</a>.

<p>The <dfn method for="NamedNodeMap"><code>item(<var>index</var>)</code></dfn> method, when
invoked, must run these steps:

<ol>
 <li><p>If <var>index</var> is equal to or greater than <a>context object</a>'s
 <a for=NamedNodeMap>attribute list</a>'s <a for=list>size</a>, then return null.

 <li><p>Otherwise, return <a>context object</a>'s
 <a for=NamedNodeMap>attribute list</a>[<var>index</var>].
</ol>

<p>A {{NamedNodeMap}} object's <a>supported property names</a> are the return value of running these
steps:

<ol>
 <li><p>Let <var>names</var> be the <a for=Attr>qualified names</a> of the <a>attributes</a> in this
 {{NamedNodeMap}} object's <a for=NamedNodeMap>attribute list</a>, with duplicates omitted, in
 order.
 <!-- Even though not all names that map to an attribute are listed, due to lowercasing, ECMAScript
      invariants are not violated. https://github.com/whatwg/dom/issues/141#issuecomment-168753410
      has details. -->

 <li>
  <p>If this {{NamedNodeMap}} object's <a for=NamedNodeMap>element</a> is in the
  <a>HTML namespace</a> and its <a for=Node>node document</a> is an <a>HTML document</a>, then
  <a for=list>for each</a> <var>name</var> in <var>names</var>:

  <ol>
   <li><p>Let <var>lowercaseName</var> be <var>name</var>, in <a>ASCII lowercase</a>.

   <li><p>If <var>lowercaseName</var> is not equal to <var>name</var>, remove <var>name</var> from
   <var>names</var>.
  </ol>

 <li><p>Return <var>names</var>.
</ol>

<p>The <dfn method for="NamedNodeMap"><code>getNamedItem(<var>qualifiedName</var>)</code></dfn>
method, when invoked, must return the result of
<a lt="get an attribute by name">getting an attribute</a> given <var>qualifiedName</var> and
<a for=NamedNodeMap>element</a>.

<p>The
<dfn method for="NamedNodeMap"><code>getNamedItemNS(<var>namespace</var>, <var>localName</var>)</code></dfn>
method, when invoked, must return the result of
<a lt="get an attribute by namespace and local name">getting an attribute</a> given
<var>namespace</var>, <var>localName</var>, and
<a for=NamedNodeMap>element</a>.

<p>The <dfn method for="NamedNodeMap"><code>setNamedItem(<var>attr</var>)</code></dfn> and
<dfn method for="NamedNodeMap"><code>setNamedItemNS(<var>attr</var>)</code></dfn>
methods, when invoked, must return the result of <a lt="set an attribute">setting an attribute</a>
given <var>attr</var> and <a for=NamedNodeMap>element</a>.

<p>The <dfn method for="NamedNodeMap"><code>removeNamedItem(<var>qualifiedName</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li><p>Let <var>attr</var> be the result of
 <a lt="remove an attribute by name">removing an attribute</a> given
 <var>qualifiedName</var> and <a for=NamedNodeMap>element</a>.

 <li><p>If <var>attr</var> is null, then <a>throw</a> a "{{NotFoundError!!exception}}"
 {{DOMException}}.

 <li><p>Return <var>attr</var>.
</ol>

<p>The
<dfn method for="NamedNodeMap"><code>removeNamedItemNS(<var>namespace</var>, <var>localName</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li><p>Let <var>attr</var> be the result of
 <a lt="remove an attribute by namespace and local name">removing an attribute</a> given
 <var>namespace</var>, <var>localName</var>, and <a for=NamedNodeMap>element</a>.

 <li><p>If <var>attr</var> is null, then <a>throw</a> a "{{NotFoundError!!exception}}"
 {{DOMException}}.

 <li><p>Return <var>attr</var>.
</ol>


<h4 id=interface-attr>Interface {{Attr}}</h4>

<pre class=idl>
[Exposed=Window]
interface Attr : Node {
  readonly attribute DOMString? namespaceURI;
  readonly attribute DOMString? prefix;
  readonly attribute DOMString localName;
  readonly attribute DOMString name;
  [CEReactions] attribute DOMString value;

  readonly attribute Element? ownerElement;

  readonly attribute boolean specified; // useless; always returns true
};</pre>

<p>{{Attr}} <a for=/>nodes</a> are simply known as
<dfn export id=concept-attribute lt="attribute">attributes</dfn>. They are sometimes referred
to as <em>content attributes</em> to avoid confusion with IDL attributes.

<a>Attributes</a> have a
<dfn export id=concept-attribute-namespace for=Attr>namespace</dfn> (null or a non-empty string),
<dfn export id=concept-attribute-namespace-prefix for=Attr>namespace prefix</dfn> (null or a non-empty string),
<dfn export id=concept-attribute-local-name for=Attr>local name</dfn> (a non-empty string),
<dfn export id=concept-attribute-value for=Attr>value</dfn> (a string), and
<dfn export id=concept-attribute-element for=Attr>element</dfn> (null or an
<a for="/">element</a>).

<p class="note no-backref">If designed today they would just have a name and value. ☹

<p>An <a>attribute</a>'s
<dfn export id=concept-attribute-qualified-name for=Attr>qualified name</dfn> is its
<a for=Attr>local name</a> if its <a for=Attr>namespace prefix</a> is null, and its
<a for=Attr>namespace prefix</a>, followed by "<code>:</code>", followed by its
<a for=Attr>local name</a>, otherwise.

<p class=note>User agents could have this as an internal slot as an optimization.

When an <a>attribute</a> is created, its
<a for=Attr>local name</a> is given. Unless explicitly
given when an <a>attribute</a> is created, its
<a for=Attr>namespace</a>,
<a for=Attr>namespace prefix</a>, and
<a for=Attr>element</a> are set to null, and its
<a for=Attr>value</a> is set to the empty string.

An
<dfn export id=concept-named-attribute lt="named attribute"><code><var>A</var></code> attribute</dfn>
is an <a>attribute</a> whose
<a for=Attr>local name</a> is
<code><var>A</var></code> and whose
<a for=Attr>namespace</a> and
<a for=Attr>namespace prefix</a> are
null.

<hr>

<p>The <dfn attribute for="Attr"><code>namespaceURI</code></dfn> attribute's getter must return the
<a for=Attr>namespace</a>.

<p>The <dfn attribute for="Attr"><code>prefix</code></dfn> attribute's getter must return the
<a for=Attr>namespace prefix</a>.

<p>The <dfn attribute for="Attr"><code>localName</code></dfn> attribute's getter must return the
<a for=Attr>local name</a>.

<p>The <dfn attribute for="Attr"><code>name</code></dfn> attribute's getter must return the
<a for=Attr>qualified name</a>.

<p>The <dfn attribute for="Attr"><code>value</code></dfn> attribute's getter must return the
<a for=Attr>value</a>.

<p>To <dfn>set an existing attribute value</dfn>, given an <a>attribute</a> <var>attribute</var> and
string <var>value</var>, run these steps:

<ol>
 <li><p>If <var>attribute</var>'s <a for=Attr>element</a> is null, then set <var>attribute</var>'s
 <a for=Attr>value</a> to <var>value</var>.

 <li><p>Otherwise, <a lt="change an attribute">change</a> <var>attribute</var> to <var>value</var>.
</ol>

<p>The {{Attr/value}} attribute's setter must <a>set an existing attribute value</a> with
<a>context object</a> and the given value.

<hr>

<p>The <dfn attribute for="Attr"><code>ownerElement</code></dfn> attribute's getter must return
<a>context object</a>'s <a for=Attr>element</a>.

<hr>

<p>The <dfn attribute for="Attr"><code>specified</code></dfn> attribute's getter must return true.


<h3 id=interface-characterdata>Interface {{CharacterData}}</h3>

<pre class=idl>
[Exposed=Window]
interface CharacterData : Node {
  attribute [TreatNullAs=EmptyString] DOMString data;
  readonly attribute unsigned long length;
  DOMString substringData(unsigned long offset, unsigned long count);
  void appendData(DOMString data);
  void insertData(unsigned long offset, DOMString data);
  void deleteData(unsigned long offset, unsigned long count);
  void replaceData(unsigned long offset, unsigned long count, DOMString data);
};
</pre>

<p class="note no-backref">{{CharacterData}} is an abstract interface and does not exist as
<a>node</a>. It is used by {{Text}}, {{ProcessingInstruction}}, and {{Comment}} <a for=/>nodes</a>.

Each <a>node</a> inheriting from the
{{CharacterData}} interface has an associated mutable string
called <dfn export id=concept-cd-data for=CharacterData>data</dfn>.

To <dfn export id=concept-cd-replace>replace data</dfn> of node <var>node</var> with offset
<var>offset</var>, count <var>count</var>, and data <var>data</var>, run these steps:

<ol>
 <li>Let <var>length</var> be <var>node</var>'s <a for=Node>length</a>.

 <li>If <var>offset</var> is greater than <var>length</var>, then <a>throw</a> an
 "{{IndexSizeError!!exception}}" {{DOMException}}.

 <li>If <var>offset</var> plus <var>count</var> is greater than <var>length</var>, then set
 <var>count</var> to <var>length</var> minus <var>offset</var>.

 <li><p><a>Queue a mutation record</a> of "<code>characterData</code>" for <var>node</var> with
 null, null, <var>node</var>'s <a for=CharacterData>data</a>, « », « », null, and null.

 <li>Insert <var>data</var> into <var>node</var>'s
 <a for=CharacterData>data</a> after <var>offset</var>
 <a>code units</a>.

 <li>Let <var>delete offset</var> be <var>offset</var> + <var>data</var>'s
 <a for="JavaScript string">length</a>.

 <li>Starting from <var>delete offset</var>
 <a>code units</a>, remove
 <var>count</var>
 <a>code units</a> from
 <var>node</var>'s <a for=CharacterData>data</a>.

 <!-- ranges -->
 <li><p>For each <a>live range</a> whose <a for=range>start node</a> is <var>node</var> and
 <a for=range>start offset</a> is greater than <var>offset</var> but less than or equal to
 <var>offset</var> plus <var>count</var>, set its <a for=range>start offset</a> to
 <var>offset</var>.

 <li><p>For each <a>live range</a> whose <a for=range>end node</a> is <var>node</var> and
 <a for=range>end offset</a> is greater than <var>offset</var> but less than or equal to
 <var>offset</var> plus <var>count</var>, set its <a for=range>end offset</a> to <var>offset</var>.

 <li><p>For each <a>live range</a> whose <a for=range>start node</a> is <var>node</var> and
 <a for=range>start offset</a> is greater than <var>offset</var> plus <var>count</var>, increase its
 <a for=range>start offset</a> by <var>data</var>'s <a for="JavaScript string">length</a> and
 decrease it by <var>count</var>.

 <li><p>For each <a>live range</a> whose <a for=range>end node</a> is <var>node</var> and
 <a for=range>end offset</a> is greater than <var>offset</var> plus <var>count</var>, increase its
 <a for=range>end offset</a> by <var>data</var>'s <a for="JavaScript string">length</a> and decrease
 it by <var>count</var>.

 <li>If <var>node</var>'s <a>parent</a> is non-null, then run the <a>children changed steps</a> for
 <var>node</var>'s <a>parent</a>.
</ol>
<!-- delete happens after insert for better cursor positioning with editing
https://www.w3.org/Bugs/Public/show_bug.cgi?id=13153 -->

<!-- If you set a node's data to a new value (e.g., using the data
attribute):

IE 9: Acts like the node was deleted and recreated, moves the boundary
points up to the parent
Firefox 4: Resets the offset to 0, always
Chrome 11 dev: Resets the offset to 0, except it does nothing if the new
data is the same as the old data
Opera 11: Sets a start offset to 0 and an end offset to the end of the
data, always

The spec originally followed WebKit, since it seemed to make the most sense.
Opera's approach of setting end offsets to the length of the new data
arguably makes more sense, but that's debatable, and it's greatly
outnumbered. However, after some feedback by bzbarsky that checking for
equality is expensive, I removed the special case and matched Firefox:

https://www.w3.org/Bugs/Public/show_bug.cgi?id=13250

Authors who want WebKit-like behavior can always use replaceData() instead.

XXX replaceData is the same as setting data these days -->


To <dfn export for="CharacterData, Text, Comment, ProcessingInstruction" id=concept-cd-substring>substring data</dfn> with node
<var>node</var>, offset <var>offset</var>, and count
<var>count</var>, run these steps:

<ol>
 <li>Let <var>length</var> be <var>node</var>'s <a for=Node>length</a>.

 <li>If <var>offset</var> is greater than <var>length</var>, then <a>throw</a> an
 "{{IndexSizeError!!exception}}" {{DOMException}}.

 <li>If <var>offset</var> plus <var>count</var> is
 greater than <var>length</var>, return a string whose value is the
 <a>code units</a> from the
 <var>offset</var><sup>th</sup>
 <a>code unit</a> to the end of
 <var>node</var>'s <a for=CharacterData>data</a>, and then
 return.

 <li>Return a string whose value is the
 <a>code units</a> from the
 <var>offset</var><sup>th</sup>
 <a>code unit</a> to the
 <var>offset</var>+<var>count</var><sup>th</sup>
 <a>code unit</a> in <var>node</var>'s
 <a for=CharacterData>data</a>.
</ol>

<p>The <dfn attribute for=CharacterData><code>data</code></dfn> attribute's getter must return
<a>context object</a>'s <a for=CharacterData>data</a>. Its setter must <a>replace data</a> with node
<a>context object</a>, offset 0, count <a>context object</a>'s <a for=Node>length</a>, and
data new value.

<p>The <dfn attribute for=CharacterData><code>length</code></dfn> attribute's getter must return
<a>context object</a>'s <a for=Node>length</a>.

<p>The
<dfn method for=CharacterData><code>substringData(<var>offset</var>, <var>count</var>)</code></dfn>
method, when invoked, must return the result of running <a>substring data</a> with node
<a>context object</a>, offset <var>offset</var>, and count <var>count</var>.

<p>The <dfn method for=CharacterData><code>appendData(<var>data</var>)</code></dfn> method, when
invoked, must <a>replace data</a> with node <a>context object</a>, offset <a>context object</a>'s
<a for=Node>length</a>, count 0, and data <var>data</var>.

<p>The
<dfn method for=CharacterData><code>insertData(<var>offset</var>, <var>data</var>)</code></dfn>
method, when invoked, must <a>replace data</a> with node <a>context object</a>, offset
<var>offset</var>, count 0, and data <var>data</var>.

<p>The
<dfn method for=CharacterData><code>deleteData(<var>offset</var>, <var>count</var>)</code></dfn>
method, when invoked, must <a>replace data</a> with node <a>context object</a>, offset
<var>offset</var>, count <var>count</var>, and data the empty string.

<p>The
<dfn method for=CharacterData><code>replaceData(<var>offset</var>, <var>count</var>, <var>data</var>)</code></dfn>
method, when invoked, must <a>replace data</a> with node <a>context object</a>, offset
<var>offset</var>, count <var>count</var>, and data <var>data</var>.


<h3 id=interface-text>Interface {{Text}}</h3>

<pre class=idl>
[Exposed=Window]
interface Text : CharacterData {
  constructor(optional DOMString data = "");

  [NewObject] Text splitText(unsigned long offset);
  readonly attribute DOMString wholeText;
};
</pre>

<dl class=domintro>
 <dt><code><var>text</var> = new <a constructor lt=Text()>Text([<var>data</var> = ""])</a></code>
 <dd>Returns a new {{Text}} <a>node</a> whose
 <a for=CharacterData>data</a> is <var>data</var>.

 <dt><code><var>text</var> . {{Text/splitText(offset)}}</code>
 <dd>Splits <a for=CharacterData>data</a> at the given
 <var>offset</var> and returns the remainder as {{Text}}
 <a>node</a>.

 <dt><code><var>text</var> . {{Text/wholeText}}</code>
 <dd>Returns the combined <a for=CharacterData>data</a> of all direct
 {{Text}} <a>node</a>
 <a for=tree>siblings</a>.
</dl>

<hr>

<p>An <dfn export>exclusive {{Text}} node</dfn> is a {{Text}} <a>node</a> that is not a
{{CDATASection}} <a>node</a>.

<p>The <dfn export>contiguous {{Text}} nodes</dfn> of a <a>node</a> <var>node</var> are
<var>node</var>, <var>node</var>'s <a>previous sibling</a> {{Text}} <a>node</a>, if any, and its
<a>contiguous <code>Text</code> nodes</a>, and <var>node</var>'s <a for=tree>next sibling</a> {{Text}}
<a>node</a>, if any, and its <a>contiguous <code>Text</code> nodes</a>, avoiding any duplicates.

<p>The <dfn export>contiguous exclusive {{Text}} nodes</dfn> of a <a>node</a> <var>node</var> are
<var>node</var>, <var>node</var>'s <a>previous sibling</a> <a>exclusive <code>Text</code> node</a>,
if any, and its <a>contiguous exclusive <code>Text</code> nodes</a>, and <var>node</var>'s
<a for=tree>next sibling</a> <a>exclusive <code>Text</code> node</a>, if any, and its
<a>contiguous exclusive <code>Text</code> nodes</a>, avoiding any duplicates.

<p>The <dfn export id=concept-child-text-content>child text content</dfn> of a <a for=/>node</a>
<var>node</var> is the <a for=string>concatenation</a> of the <a for=CharacterData>data</a> of all
the {{Text}} <a for=/>node</a> <a>children</a> of <var>node</var>, in <a>tree order</a>.

<p>The <dfn export id=concept-descendant-text-content>descendant text content</dfn> of a
<a for=/>node</a> <var>node</var> is the <a for=string>concatenation</a> of the
<a for=CharacterData>data</a> of all the {{Text}} <a for=/>node</a> <a>descendants</a> of
<var>node</var>, in <a>tree order</a>.

<hr>

<p>The <dfn constructor for=Text><code>Text(<var>data</var>)</code></dfn> constructor, when invoked,
must return a new {{Text}} <a>node</a> whose <a for=CharacterData>data</a> is <var>data</var> and
<a for=Node>node document</a> is <a>current global object</a>'s
<a>associated <code>Document</code></a>.

To <dfn export id=concept-text-split lt="split a Text node">split</dfn> a {{Text}}
<a>node</a> <var>node</var> with offset
<var>offset</var>, run these steps:

<ol>
 <li>Let <var>length</var> be <var>node</var>'s <a for=Node>length</a>.

 <li>If <var>offset</var> is greater than <var>length</var>, then <a>throw</a> an
 "{{IndexSizeError!!exception}}" {{DOMException}}.

 <li>Let <var>count</var> be <var>length</var> minus
 <var>offset</var>.

 <li>Let <var>new data</var> be the result of
 <a lt="substring data">substringing data</a> with node
 <var>node</var>, offset <var>offset</var>, and count
 <var>count</var>.

 <li>Let <var>new node</var> be a new {{Text}}
 <a>node</a>, with the same
 <a for=Node>node document</a> as
 <var>node</var>. Set <var>new node</var>'s
 <a for=CharacterData>data</a> to <var>new data</var>.

 <li>Let <var>parent</var> be <var>node</var>'s
 <a for=tree>parent</a>.

 <li>
  <p>If <var>parent</var> is not null, then:

  <ol>
   <li><p><a for=/>Insert</a> <var>new node</var> into <var>parent</var> before <var>node</var>'s
   <a for=tree>next sibling</a>.
   <!-- Do this before we replace data, so that the data replacement won't
   mutate ranges prematurely:
   https://www.w3.org/Bugs/Public/show_bug.cgi?id=15325 -->

   <li><p>For each <a>live range</a> whose <a for=range>start node</a> is <var>node</var> and
   <a for=range>start offset</a> is greater than <var>offset</var>, set its
   <a for=range>start node</a> to <var>new node</var> and decrease its <a for=range>start offset</a>
   by <var>offset</var>.

   <li><p>For each <a>live range</a> whose <a for=range>end node</a> is <var>node</var> and
   <a for=range>end offset</a> is greater than <var>offset</var>, set its <a for=range>end node</a>
   to <var>new node</var> and decrease its <a for=range>end offset</a> by <var>offset</var>.

   <!-- This shit is complicated:
        https://www.w3.org/Bugs/Public/show_bug.cgi?id=19968 -->
   <li><p>For each <a>live range</a> whose <a for=range>start node</a> is <var>parent</var> and
   <a for=range>start offset</a> is equal to the <a for=tree>index</a> of <var>node</var> plus 1,
   increase its <a for=range>start offset</a> by 1.

   <li><p>For each <a>live range</a> whose <a for=range>end node</a> is <var>parent</var> and
   <a for=range>end offset</a> is equal to the <a for=tree>index</a> of <var>node</var> plus 1,
   increase its <a for=range>end offset</a> by 1.
  </ol>

 <li><a>Replace data</a> with node
 <var>node</var>, offset <var>offset</var>, count
 <var>count</var>, and data the empty string.

 <li>Return <var>new node</var>.
</ol>

<p>The <dfn method for=Text><code>splitText(<var>offset</var>)</code></dfn> method, when invoked,
must <a lt="split a Text node">split</a> <a>context object</a> with offset <var>offset</var>.

<p>The <dfn attribute for=Text><code>wholeText</code></dfn> attribute's getter must return the
<a for=string>concatenation</a> of the <a for=CharacterData>data</a> of the
<a>contiguous <code>Text</code> nodes</a> of the <a>context object</a>, in <a>tree order</a>.


<h3 id=interface-cdatasection>Interface {{CDATASection}}</h3>

<pre class=idl>
[Exposed=Window]
interface CDATASection : Text {
};</pre>


<h3 id=interface-processinginstruction>Interface {{ProcessingInstruction}}</h3>

<pre class=idl>
[Exposed=Window]
interface ProcessingInstruction : CharacterData {
  readonly attribute DOMString target;
};</pre>


{{ProcessingInstruction}} <a for=/>nodes</a>
have an associated <dfn export id=concept-pi-target for=ProcessingInstruction>target</dfn>.

The <dfn attribute for=ProcessingInstruction>target</dfn>
attribute must return the <a for=ProcessingInstruction>target</a>.


<h3 id=interface-comment>Interface {{Comment}}</h3>

<pre class=idl>
[Exposed=Window]
interface Comment : CharacterData {
  constructor(optional DOMString data = "");
};
</pre>

<dl class=domintro>
 <dt><code><var ignore>comment</var> = new <a constructor lt="Comment()">Comment([<var>data</var> = ""])</a></code>
 <dd>Returns a new {{Comment}} <a>node</a> whose
 <a for=CharacterData>data</a> is <var>data</var>.
</dl>

<p>The <dfn constructor for=Comment><code>Comment(<var>data</var>)</code></dfn> constructor, when
invoked, must return a new {{Comment}} <a>node</a> whose <a for=CharacterData>data</a> is
<var>data</var> and <a for=Node>node document</a> is <a>current global object</a>'s
<a>associated <code>Document</code></a>.




<h2 id=ranges>Ranges</h2>

<h3 id=introduction-to-dom-ranges>Introduction to "DOM Ranges"</h3>

<p>{{StaticRange}} and {{Range}} objects (<a>ranges</a>) represent a sequence of content within a
<a>node tree</a>. Each <a>range</a> has a <a for=range>start</a> and an <a for=range>end</a> which
are <a>boundary points</a>. A <a>boundary point</a> is a <a for=/>tuple</a> consisting of a
<a for="boundary point">node</a> and an <a for="boundary point">offset</a>. So in other words, a
<a>range</a> represents a piece of content within a <a>node tree</a> between two
<a>boundary points</a>.

<p><a>Ranges</a> are frequently used in editing for selecting and copying content.

<ul class="domTree">
 <li class="t1">{{Element}}: <code>p</code>
  <ul>
   <li class="t1">{{Element}}: <code class='lang-markup'>&lt;img src="insanity-wolf" alt="Little-endian BOM; decode as big-endian!"></code>
   <li class="t3">{{Text}}: <span>&nbsp;CSS 2.1 syndata is&nbsp;</span>
   <li class="t1">{{Element}}: <code class='lang-markup'>&lt;em></code>
    <ul>
     <li class="t3">{{Text}}: <span>awesome</span>
    </ul>
   <li class="t3">{{Text}}: <span>!</span>
  </ul>
</ul>
<!-- http://w3cmemes.tumblr.com/post/35332222321/css-2-1-syndata-is-awesome -->

<p>In the <a>node tree</a> above, a
<a>range</a> can be used to represent the sequence
“syndata is awes”. Assuming <var ignore>p</var> is assigned to the
<code>p</code> <a for="/">element</a>, and
<var ignore>em</var> to the <code>em</code>
<a for="/">element</a>, this would be done as follows:

<pre class='lang-javascript'><code>
var range = new Range(),
    firstText = p.childNodes[1],
    secondText = em.firstChild
range.setStart(firstText, 9) // do not forget the leading space
range.setEnd(secondText, 4)
// range now stringifies to the aforementioned quote
</code></pre>

<p class="note no-backref"><a>Attributes</a> such as <code>src</code> and <code>alt</code> in the
<a>node tree</a> above cannot be represented by a <a>range</a>. <a>Ranges</a> are only useful for
<a for=/>nodes</a>.

<p>{{Range}} objects, unlike {{StaticRange}} objects, are affected by mutations to the
<a>node tree</a>. Therefore they are also known as <a>live ranges</a>. Such mutations will not
invalidate them and will try to ensure that it still represents the same piece of content.
Necessarily, a <a>live range</a> might itself be modified as part of the mutation to the
<a>node tree</a> when, e.g., part of the content it represents is mutated.

<p class="note no-backref">See the <a for=/>insert</a> and <a for=/>remove</a> algorithms, the
{{Node/normalize()}} method, and the <a>replace data</a> and <a lt="split a Text node">split</a>
algorithms for details.

<p>Updating <a>live ranges</a> in response to <a>node tree</a> mutations can be expensive. For every
<a>node tree</a> change, all affected {{Range}} objects need to be updated. Even if the application
is uninterested in some <a>live ranges</a>, it still has to pay the cost of keeping them up-to-date
when a mutation occurs.

<p>A {{StaticRange}} object is a lightweight <a>range</a> that does not update when the
<a>node tree</a> mutates. It is therefore not subject to the same maintenance cost as
<a>live ranges</a>.


<h3 id=boundary-points>Boundary points</h3>

<p>A <dfn export id=concept-range-bp>boundary point</dfn> is a <a for=/>tuple</a> consisting of a
<dfn export for="boundary point">node</dfn> (a <a for=/>node</a>) and an
<dfn export id=concept-range-bp-offset for="boundary point">offset</dfn> (a non-negative integer).

<p class="note no-backref">A correct <a>boundary point</a>'s <a for="boundary point">offset</a> will
be between 0 and the <a>boundary point</a>'s <a for="boundary point">node</a>'s
<a for=Node>length</a>, inclusive.

<p>The <dfn export id=concept-range-bp-position for="boundary point">position</dfn> of a
<a>boundary point</a> (<var>nodeA</var>, <var>offsetA</var>) relative to a <a>boundary point</a>
(<var>nodeB</var>, <var>offsetB</var>) is
<dfn export id=concept-range-bp-before for="boundary point">before</dfn>,
<dfn export id=concept-range-bp-equal for="boundary point">equal</dfn>, or
<dfn export id=concept-range-bp-after for="boundary point">after</dfn>, as returned by these steps:

<ol>
 <li><p>Assert: <var>nodeA</var> and <var>nodeB</var> have the same <a for=tree>root</a>.

 <li>If <var>nodeA</var> is <var>nodeB</var>, then return <a for="boundary point">equal</a> if
 <var>offsetA</var> is <var>offsetB</var>, <a for="boundary point">before</a> if <var>offsetA</var>
 is less than <var>offsetB</var>, and <a for="boundary point">after</a> if <var>offsetA</var> is
 greater than <var>offsetB</var>.

 <li><p>If <var>nodeA</var> is <a>following</a> <var>nodeB</var>, then if the
 <a for="boundary point">position</a> of (<var>nodeB</var>, <var>offsetB</var>) relative to
 (<var>nodeA</var>, <var>offsetA</var>) is <a for="boundary point">before</a>, return
 <a for="boundary point">after</a>, and if it is <a for="boundary point">after</a>, return
 <a for="boundary point">before</a>.

 <li>
  <p>If <var>nodeA</var> is an <a>ancestor</a> of <var>nodeB</var>:

  <ol>
   <li><p>Let <var>child</var> be <var>nodeB</var>.

   <li><p>While <var>child</var> is not a <a for=tree>child</a> of <var>nodeA</var>, set
   <var>child</var> to its <a for=tree>parent</a>.

   <li><p>If <var>child</var>'s <a for=tree>index</a> is less than <var>offsetA</var>, then return
   <a for="boundary point">after</a>.
  </ol>

 <li><p>Return <a for="boundary point">before</a>.
</ol>


<h3 id=interface-abstractrange>Interface {{AbstractRange}}</h3>

<pre class=idl>
[Exposed=Window]
interface AbstractRange {
  readonly attribute Node startContainer;
  readonly attribute unsigned long startOffset;
  readonly attribute Node endContainer;
  readonly attribute unsigned long endOffset;
  readonly attribute boolean collapsed;
};
</pre>

<p>Objects implementing the {{AbstractRange}} interface are known as
<dfn export id=concept-range lt="range">ranges</dfn>.

<p>A <a>range</a> has two associated <a>boundary points</a> — a
<dfn export id=concept-range-start for=range>start</dfn> and
<dfn export id=concept-range-end for=range>end</dfn>.

<p>For convenience, a <a>range</a>'s
<dfn export id=concept-range-start-node for=range>start node</dfn> is its <a for=range>start</a>'s
<a for="boundary point">node</a>, its
<dfn export id=concept-range-start-offset for=range>start offset</dfn> is its
<a for=range>start</a>'s <a for="boundary point">offset</a>, its
<dfn export id=concept-range-end-node for=range>end node</dfn> is its <a for=range>end</a>'s
<a for="boundary point">node</a>,  and its
<dfn export id=concept-range-end-offset for=range>end offset</dfn> is its <a for=range>end</a>'s
<a for="boundary point">offset</a>.

<p>A <a>range</a> is <dfn for=range export>collapsed</dfn> if its <a for=range>start node</a> is its
<a for=range>end node</a> and its <a for=range>start offset</a> is its <a for=range>end offset</a>.

<dl class=domintro>
 <dt><code><var>node</var> = <var>range</var> . <a attribute for=AbstractRange>startContainer</a></code>
 <dd>Returns <var>range</var>'s <a for=range>start node</a>.

 <dt><code><var>offset</var> = <var>range</var> . <a attribute for=AbstractRange>startOffset</a></code>
 <dd>Returns <var>range</var>'s <a for=range>start offset</a>.

 <dt><code><var>node</var> = <var>range</var> . <a attribute for=AbstractRange>endContainer</a></code>
 <dd>Returns <var>range</var>'s <a for=range>end node</a>.

 <dt><code><var>offset</var> = <var>range</var> . <a attribute for=AbstractRange>endOffset</a></code>
 <dd>Returns <var>range</var>'s <a for=range>end offset</a>.

 <dt><code><var ignore>collapsed</var> = <var>range</var> . <a attribute for=AbstractRange>collapsed</a></code>
 <dd>Returns true if <var>range</var> is <a for=range>collapsed</a>, and false otherwise.
</dl>

<p>The
<dfn id=dom-range-startcontainer attribute for=AbstractRange><code>startContainer</code></dfn>
attribute's getter must return the <a>context object</a>'s <a for=range>start node</a>.

<p>The <dfn id=dom-range-startoffset attribute for=AbstractRange><code>startOffset</code></dfn>
attribute's getter must return the <a>context object</a>'s <a for=range>start offset</a>.

<p>The <dfn id=dom-range-endcontainer attribute for=AbstractRange><code>endContainer</code></dfn>
attribute's getter must return the <a>context object</a>'s <a for=range>end node</a>.

<p>The <dfn id=dom-range-endoffset attribute for=AbstractRange><code>endOffset</code></dfn>
attribute's getter must return the <a>context object</a>'s <a for=range>end offset</a>.

<p>The <dfn id=dom-range-collapsed attribute for=AbstractRange><code>collapsed</code></dfn>
attribute's getter must return true if the <a>context object</a> is <a for=range>collapsed</a>, and
false otherwise.


<h3 id=interface-staticrange>Interface {{StaticRange}}</h3>

<pre class=idl>
dictionary StaticRangeInit {
  required Node startContainer;
  required unsigned long startOffset;
  required Node endContainer;
  required unsigned long endOffset;
};

[Exposed=Window]
interface StaticRange : AbstractRange {
  constructor(StaticRangeInit init);
};
</pre>

<dl class=domintro>
 <dt><code><var>staticRange</var> = new <a constructor lt="StaticRange(init)">StaticRange</a>(init)</code>
 <dd><p>Returns a new <a>range</a> object that does not update when the <a>node tree</a> mutates.
</dl>

<p>The <dfn constructor for=StaticRange><code>StaticRange(<var>init</var>)</code></dfn> constructor,
when invoked, must run these steps:

<ol>
 <li><p>If <var>init</var>'s {{StaticRangeInit/startContainer}} or {{StaticRangeInit/endContainer}}
 is a {{DocumentType}} or {{Attr}} <a for=/>node</a>, then <a>throw</a> an
 "{{InvalidNodeTypeError!!exception}}" {{DOMException}}.

 <li><p>Let <var>staticRange</var> be a new {{StaticRange}} object.

 <li><p>Set <var>staticRange</var>'s <a for=range>start</a> to (<var>init</var>'s
 {{StaticRangeInit/startContainer}}, <var>init</var>'s {{StaticRangeInit/startOffset}}) and
 <a for=range>end</a> to (<var>init</var>'s {{StaticRangeInit/endContainer}}, <var>init</var>'s
 {{StaticRangeInit/endOffset}}).

 <li><p>Return <var>staticRange</var>.
</ol>


<h3 id=interface-range>Interface {{Range}}</h3>

<pre class=idl>
[Exposed=Window]
interface Range : AbstractRange {
  constructor();

  readonly attribute Node commonAncestorContainer;

  void setStart(Node node, unsigned long offset);
  void setEnd(Node node, unsigned long offset);
  void setStartBefore(Node node);
  void setStartAfter(Node node);
  void setEndBefore(Node node);
  void setEndAfter(Node node);
  void collapse(optional boolean toStart = false);
  void selectNode(Node node);
  void selectNodeContents(Node node);

  const unsigned short START_TO_START = 0;
  const unsigned short START_TO_END = 1;
  const unsigned short END_TO_END = 2;
  const unsigned short END_TO_START = 3;
  short compareBoundaryPoints(unsigned short how, Range sourceRange);

  [CEReactions] void deleteContents();
  [CEReactions, NewObject] DocumentFragment extractContents();
  [CEReactions, NewObject] DocumentFragment cloneContents();
  [CEReactions] void insertNode(Node node);
  [CEReactions] void surroundContents(Node newParent);

  [NewObject] Range cloneRange();
  void detach();

  boolean isPointInRange(Node node, unsigned long offset);
  short comparePoint(Node node, unsigned long offset);

  boolean intersectsNode(Node node);

  stringifier;
};
</pre>

<p>Objects implementing the {{Range}} interface are known as
<dfn export id=concept-live-range>live ranges</dfn>.

<p class="note">Algorithms that modify a <a>tree</a> (in particular the <a for=/>insert</a>,
<a for=/>remove</a>, <a>replace data</a>, and <a lt="split a Text node">split</a> algorithms) modify
<a>live ranges</a> associated with that <a>tree</a>.

<p>The <dfn export id=concept-range-root for="live range">root</dfn> of a <a>live range</a> is the
<a for=tree>root</a> of its <a for=range>start node</a>.
<!-- start and end have an identical root -->

<p>A <a for=/>node</a> <var>node</var> is <dfn export for="live range" id=contained>contained</dfn>
in a <a>live range</a> <var>range</var> if <var>node</var>'s <a for=tree>root</a> is
<var>range</var>'s <a for="live range">root</a>, and (<var>node</var>, 0) is
<a for="boundary point">after</a> <var>range</var>'s <a for=range>start</a>, and
(<var>node</var>, <var>node</var>'s <a>length</a>) is <a for="boundary point">before</a>
<var>range</var>'s <a for=range>end</a>.

<p>A <a for=/>node</a> is
<dfn export for="live range" id=partially-contained>partially contained</dfn> in a <a>live range</a>
if it's an <a for=tree>inclusive ancestor</a> of the <a>live range</a>'s <a for=range>start node</a>
but not its <a for=range>end node</a>, or vice versa.

<div class="note no-backref">
 <p>Some facts to better understand these definitions:

 <ul>
  <li><p>The content that one would think of as being within the <a>live range</a> consists of all
  <a for="live range">contained</a> <a for=/>nodes</a>, plus possibly some of the contents of the
  <a for=range>start node</a> and <a for=range>end node</a> if those are {{Text}},
  {{ProcessingInstruction}}, or {{Comment}} <a for=/>nodes</a>.

  <li><p>The <a for=/>nodes</a> that are contained in a <a>live range</a> will generally not be
  contiguous, because the <a for=tree>parent</a> of a <a for="live range">contained</a>
  <a for=/>node</a> will not always be <a for="live range">contained</a>.

  <li><p>However, the <a>descendants</a> of a <a for="live range">contained</a> <a for=/>node</a>
  are <a for="live range">contained</a>, and if two <a for=tree>siblings</a> are
  <a for="live range">contained</a>, so are any <a for=tree>siblings</a> that lie between them.

  <li><p>The <a for=range>start node</a> and <a for=range>end node</a> of a <a>live range</a> are
  never <a for="live range">contained</a> within it.

  <li><p>The first <a for="live range">contained</a> <a for=/>node</a> (if there are any) will
  always be after the <a for=range>start node</a>, and the last <a for="live range">contained</a>
  <a for=/>node</a> will always be equal to or before the <a for=range>end node</a>'s last
  <a>descendant</a>.

  <li><p>There exists a <a for="live range">partially contained</a> <a for=/>node</a> if and only if
  the <a for=range>start node</a> and <a for=range>end node</a> are different.

  <li><p>The {{Range/commonAncestorContainer}} attribute value is neither
  <a for="live range">contained</a> nor <a for="live range">partially contained</a>.

  <li><p>If the <a for=range>start node</a> is an <a>ancestor</a> of the <a for=range>end node</a>,
  the common <a for=tree>inclusive ancestor</a> will be the <a for=range>start node</a>. Exactly one
  of its <a>children</a> will be <a for="live range">partially contained</a>, and a
  <a for=tree>child</a> will be <a for="live range">contained</a> if and only if it
  <a lt="preceding">precedes</a> the <a for="live range">partially contained</a>
  <a for=tree>child</a>. If the <a for=range>end node</a> is an <a>ancestor</a> of the
  <a for=range>start node</a>, the opposite holds.

  <li><p>If the <a for=range>start node</a> is not an <a for=tree>inclusive ancestor</a> of the
  <a for=range>end node</a>, nor vice versa, the common <a for=tree>inclusive ancestor</a> will be
  distinct from both of them. Exactly two of its <a>children</a> will be
  <a for="live range">partially contained</a>, and a <a for=tree>child</a> will be contained if and
  only if it lies between those two.
 </ul>
</div>

<hr>

<dl class=domintro>
 <dt><code><var>range</var> = new <a constructor>Range()</a></code>
 <dd>Returns a new <a>live range</a>.
</dl>

<p>The <dfn constructor for=Range><code>Range()</code></dfn> constructor, when invoked, must return
a new <a>live range</a> with
(<a>current global object</a>'s <a>associated <code>Document</code></a>, 0) as its
<a for=range>start</a> and <a for=range>end</a>.

<hr>

<dl class=domintro>
 <dt><var>container</var> = <var>range</var> . {{Range/commonAncestorContainer}}
 <dd>Returns the <a>node</a>, furthest away from
 the <a>document</a>, that is an
 <a>ancestor</a> of both
 <var>range</var>'s
 <a for=range>start node</a> and
 <a for=range>end node</a>.
</dl>

<p>The <dfn attribute for=Range><code>commonAncestorContainer</code></dfn> attribute's getter must
run these steps:

<ol>
 <li>Let <var>container</var> be
 <a for=range>start node</a>.

 <li>While <var>container</var> is not an
 <a for=tree>inclusive ancestor</a> of
 <a for=range>end node</a>, let
 <var>container</var> be <var>container</var>'s
 <a for=tree>parent</a>.

 <li>Return <var>container</var>.
</ol>

<hr>

<p>To
<dfn export id=concept-range-bp-set lt="set the start|set the end" for=Range>set the start or end</dfn>
of a <var>range</var> to a <a>boundary point</a> (<var>node</var>, <var>offset</var>), run these
steps:

<ol>
 <li>If <var>node</var> is a <a>doctype</a>, then <a>throw</a> an
 "{{InvalidNodeTypeError!!exception}}" {{DOMException}}.

 <li>If <var>offset</var> is greater than <var>node</var>'s <a>length</a>, then <a>throw</a> an
 "{{IndexSizeError!!exception}}" {{DOMException}}.

 <li>Let <var>bp</var> be the
 <a>boundary point</a>
 (<var>node</var>, <var>offset</var>).

 <li>
  <dl class=switch>
   <dt>If these steps were invoked as "set the start"
   <dd>
    <ol>
     <li>If <var>bp</var> is
     <a for="boundary point">after</a> the
     <var>range</var>'s <a for=range>end</a>, or
     if <var>range</var>'s
     <a for="live range">root</a> is not equal to
     <var>node</var>'s <a for=tree>root</a>, set
     <var>range</var>'s <a for=range>end</a> to
     <var>bp</var>.

     <li>Set <var>range</var>'s
     <a for=range>start</a> to <var>bp</var>.
    </ol>
   <dt>If these steps were invoked as "set the end"
   <dd>
    <ol>
     <li>If <var>bp</var> is
     <a for="boundary point">before</a> the
     <var>range</var>'s <a for=range>start</a>,
     or if <var>range</var>'s
     <a for="live range">root</a> is not equal to
     <var>node</var>'s <a for=tree>root</a>, set
     <var>range</var>'s <a for=range>start</a>
     to <var>bp</var>.

     <li>Set <var>range</var>'s
     <a for=range>end</a> to <var>bp</var>.
    </ol>
  </dl>
</ol>

<p>The <dfn method for=Range><code>setStart(<var>node</var>, <var>offset</var>)</code></dfn> method,
when invoked, must <a>set the start</a> of <a>context object</a> to <a>boundary point</a>
(<var>node</var>, <var>offset</var>).

<p>The <dfn method for=Range><code>setEnd(<var>node</var>, <var>offset</var>)</code></dfn> method,
when invoked, must <a>set the end</a> of <a>context object</a> to <a>boundary point</a>
(<var>node</var>, <var>offset</var>).

<p>The <dfn method for=Range><code>setStartBefore(<var>node</var>)</code></dfn> method, when
invoked, must run these steps:

<ol>
 <li>Let <var>parent</var> be <var>node</var>'s
 <a for=tree>parent</a>.

 <li>If <var>parent</var> is null, then <a>throw</a> an "{{InvalidNodeTypeError!!exception}}"
 {{DOMException}}.

 <li><a>Set the start</a> of the
 <a>context object</a> to
 <a>boundary point</a>
 (<var>parent</var>, <var>node</var>'s
 <a for=tree>index</a>).
</ol>

<p>The <dfn method for=Range><code>setStartAfter(<var>node</var>)</code></dfn> method, when invoked,
must run these steps:

<ol>
 <li><p>Let <var>parent</var> be <var>node</var>'s <a for=tree>parent</a>.

 <li><p>If <var>parent</var> is null, then <a>throw</a> an "{{InvalidNodeTypeError!!exception}}"
 {{DOMException}}.

 <li><p><a>Set the start</a> of the <a>context object</a> to <a>boundary point</a>
 (<var>parent</var>, <var>node</var>'s <a for=tree>index</a> plus 1).
</ol>

<p>The <dfn method for=Range><code>setEndBefore(<var>node</var>)</code></dfn>, when invoked, method
must run these steps:

<ol>
 <li>Let <var>parent</var> be <var>node</var>'s
 <a for=tree>parent</a>.

 <li>If <var>parent</var> is null, then <a>throw</a> an "{{InvalidNodeTypeError!!exception}}"
 {{DOMException}}.

 <li><a>Set the end</a> of the
 <a>context object</a> to
 <a>boundary point</a>
 (<var>parent</var>, <var>node</var>'s <a for=tree>index</a>).
</ol>

<p>The <dfn method for=Range><code>setEndAfter(<var>node</var>)</code></dfn> method, when invoked,
must run these steps:

<ol>
 <li><p>Let <var>parent</var> be <var>node</var>'s <a for=tree>parent</a>.

 <li><p>If <var>parent</var> is null, then <a>throw</a> an "{{InvalidNodeTypeError!!exception}}"
 {{DOMException}}.

 <li><p><a>Set the end</a> of the <a>context object</a> to <a>boundary point</a>
 (<var>parent</var>, <var>node</var>'s <a for=tree>index</a> plus 1).
</ol>

<p>The <dfn method for=Range><code>collapse(<var>toStart</var>)</code></dfn> method, when invoked,
must if <var>toStart</var> is true, set <a for=range>end</a> to <a for=range>start</a>, and set
<a for=range>start</a> to <a for=range>end</a> otherwise.

<p>To <dfn export id=concept-range-select for=range>select</dfn> a <a for=/>node</a> <var>node</var>
within a <a>range</a> <var>range</var>, run these steps:

<ol>
 <li><p>Let <var>parent</var> be <var>node</var>'s <a for=tree>parent</a>.

 <li><p>If <var>parent</var> is null, then <a>throw</a> an "{{InvalidNodeTypeError!!exception}}"
 {{DOMException}}.

 <li><p>Let <var>index</var> be <var>node</var>'s <a for=tree>index</a>.

 <li><p>Set <var>range</var>'s <a for=range>start</a> to <a>boundary point</a>
 (<var>parent</var>, <var>index</var>).

 <li><p>Set <var>range</var>'s <a for=range>end</a> to <a>boundary point</a>
 (<var>parent</var>, <var>index</var> plus 1).
</ol>

<p>The <dfn method for=Range><code>selectNode(<var>node</var>)</code></dfn> method, when invoked,
must <a for=range>select</a> <var>node</var> within <a>context object</a>.

<p>The <dfn method for=Range><code>selectNodeContents(<var>node</var>)</code></dfn> method, when
invoked, must run these steps:

<ol>
 <li>If <var>node</var> is a
 <a>doctype</a>,
 <a>throw</a> an
 "{{InvalidNodeTypeError!!exception}}" {{DOMException}}.

 <li>Let <var>length</var> be the
 <a>length</a> of <var>node</var>.

 <li>Set <a for=range>start</a> to the
 <a>boundary point</a>
 (<var>node</var>, 0).

 <li>Set <a for=range>end</a> to the
 <a>boundary point</a>
 (<var>node</var>, <var>length</var>).
</ol>

<hr>

<p>The
<dfn method for=Range><code>compareBoundaryPoints(<var>how</var>, <var>sourceRange</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li>
  <p>If <var>how</var> is not one of

  <ul class=brief>
   <li>{{Range/START_TO_START}},
   <li>{{Range/START_TO_END}},
   <li>{{Range/END_TO_END}}, and
   <li>{{Range/END_TO_START}},
  </ul>

  <p>then <a>throw</a> a "{{NotSupportedError!!exception}}" {{DOMException}}.
 <!--
 Apparent behaviors from black-box testing:

 IE9: Converts to unsigned short per WebIDL, then throws "Error: Invalid
 argument." if it's not 0-3.

 Firefox 12.0a1: Converts to unsigned short per WebIDL, then throws
 NS_ERROR_ILLEGAL_VALUE if it's not 0-3.

 Chrome 17 dev: Converts to unsigned *long* per WebIDL, and treats bad values
 as 0.  Never throws.

 Opera Next 12.00 alpha: Throws NotSupportedError unless the value is -0, 0, 1,
 2, 3, or an integer equal to one of these modulo 2^32.  (In particular, it
 throws on NaN, Infinity, and -Infinity instead of treating them as 0 per
 WebIDL.)

 The spec follows IE9/Gecko, except that we throw NotSupportedError (like
 Opera) instead of a nonstandard exception type.
 -->

 <li>If <a>context object</a>'s <a for="live range">root</a> is not the same as <var>sourceRange</var>'s
 <a for="live range">root</a>, then <a>throw</a> a "{{WrongDocumentError!!exception}}" {{DOMException}}.

 <li>
  If <var>how</var> is:
  <dl class=switch>
   <dt>{{Range/START_TO_START}}:
   <dd>
    Let <var>this point</var> be the <a>context object</a>'s
    <a for=range>start</a>.
    Let <var>other point</var> be <var>sourceRange</var>'s
    <a for=range>start</a>.

   <dt>{{Range/START_TO_END}}:
   <dd>
    Let <var>this point</var> be the <a>context object</a>'s
    <a for=range>end</a>.
    Let <var>other point</var> be <var>sourceRange</var>'s
    <a for=range>start</a>.

    <dt>{{Range/END_TO_END}}:
    <dd>
     Let <var>this point</var> be the <a>context object</a>'s
     <a for=range>end</a>.
     Let <var>other point</var> be <var>sourceRange</var>'s
     <a for=range>end</a>.

    <dt>{{Range/END_TO_START}}:
    <dd>
     Let <var>this point</var> be the <a>context object</a>'s
     <a for=range>start</a>.
     Let <var>other point</var> be <var>sourceRange</var>'s
     <a for=range>end</a>.
   </dl>

  <li>
   <p>If the <a for="boundary point">position</a> of <var>this point</var> relative to
   <var>other point</var> is

   <dl class=switch>
    <dt><a for="boundary point">before</a>
    <dd>Return &minus;1.

    <dt><a for="boundary point">equal</a>
    <dd>Return 0.

    <dt><a for="boundary point">after</a>
    <dd>Return 1.
   </dl>
</ol>

<p>The <dfn method for=Range><code>deleteContents()</code></dfn> method, when invoked, must
run these steps:

<ol>
 <li><p>If the <a>context object</a> is <a for=range>collapsed</a>, then return.
 <!-- This might actually make no difference, but it's not immediately
 obvious what would happen otherwise if the start/end were text/comment:
 are all the substeps of the next step actually no-ops, or could some have
 side effects? -->

 <li>Let <var>original start node</var>,
 <var>original start offset</var>, <var>original end node</var>,
 and <var>original end offset</var> be the
 <a>context object</a>'s
 <a for=range>start node</a>,
 <a for=range>start offset</a>,
 <a for=range>end node</a>, and
 <a for=range>end offset</a>, respectively.

 <li>If <var>original start node</var> and
 <var>original end node</var> are the same, and they are a
 {{Text}}, {{ProcessingInstruction}}, or
 {{Comment}} <a>node</a>,
 <a>replace data</a> with node
 <var>original start node</var>, offset
 <var>original start offset</var>, count
 <var>original end offset</var> minus
 <var>original start offset</var>, and data the empty string, and then return.

 <li>Let <var>nodes to remove</var> be a list of all the
 <a for=/>nodes</a> that are <a for="live range">contained</a> in
 the <a>context object</a>, in
 <a>tree order</a>, omitting any
 <a>node</a> whose
 <a for=tree>parent</a> is also
 <a for="live range">contained</a> in the <a>context object</a>.

 <li>If <var>original start node</var> is an
 <a for=tree>inclusive ancestor</a> of
 <var>original end node</var>, set
 <var>new node</var> to <var>original start node</var> and
 <var>new offset</var> to <var>original start offset</var>.

 <li>
  Otherwise:
  <ol>
   <li>Let <var>reference node</var> equal
   <var>original start node</var>.

   <li>While <var>reference node</var>'s
   <a for=tree>parent</a> is not null and is not an
   <a for=tree>inclusive ancestor</a> of
   <var>original end node</var>, set <var>reference node</var>
   to its <a for=tree>parent</a>.

   <li>
    Set <var>new node</var> to the
    <a for=tree>parent</a> of
    <var>reference node</var>, and <var>new offset</var> to one
    plus the <a for=tree>index</a> of
    <var>reference node</var>.

    <p class="note no-backref">If <var>reference node</var>'s
    <a for=tree>parent</a> were null, it would be the
    <a for="live range">root</a> of the
    <a>context object</a>, so would be an
    <a for=tree>inclusive ancestor</a> of
    <var>original end node</var>, and we could not reach this point.
  </ol>

 <li>If <var>original start node</var> is a {{Text}},
 {{ProcessingInstruction}}, or {{Comment}}
 <a>node</a>,
 <a>replace data</a> with node
 <var>original start node</var>, offset
 <var>original start offset</var>, count
 <var>original start node</var>'s
 <a>length</a> minus
 <var>original start offset</var>, data the empty string.

 <li><p>For each <var>node</var> in <var>nodes to remove</var>, in <a>tree order</a>,
 <a for=/>remove</a> <var>node</var>.

 <li>If <var>original end node</var> is a {{Text}},
 {{ProcessingInstruction}}, or {{Comment}}
 <a>node</a>,
 <a>replace data</a> with node
 <var>original end node</var>, offset 0, count
 <var>original end offset</var> and data the empty string.

 <li>Set <a for=range>start</a> and
 <a for=range>end</a> to
 (<var>new node</var>, <var>new offset</var>).
</ol>

<p>To <dfn export id=concept-range-extract for="live range">extract</dfn> a <a>live range</a>
<var>range</var>, run these steps:

<ol>
 <li><p>Let <var>fragment</var> be a new {{DocumentFragment}} <a for=/>node</a> whose
 <a for=Node>node document</a> is <var>range</var>'s <a for=range>start node</a>'s
 <a for=Node>node document</a>.

 <li><p>If <var>range</var> is <a for=range>collapsed</a>, then return <var>fragment</var>.
 <!-- This is only really needed when the start and end nodes are
 text/comment, to avoid creating an empty clone as the child of the
 fragment. (Opera 11 actually does include such an empty clone, it seems,
 but Gecko and WebKit do not as of March 2011, so we follow them.)
 Otherwise, the following steps are all no-ops. But it's simplest to include
 this step anyway. -->

 <li>Let <var>original start node</var>, <var>original start offset</var>,
 <var>original end node</var>, and <var>original end offset</var> be
 <var>range</var>'s <a for=range>start node</a>,
 <a for=range>start offset</a>,
 <a for=range>end node</a>, and
 <a for=range>end offset</a>, respectively.

 <li>
  If <var>original start node</var> is <var>original end node</var>, and they are a
  {{Text}}, {{ProcessingInstruction}}, or {{Comment}} <a>node</a>:

  <ol>
   <li>Let <var>clone</var> be a
   <a lt="clone a node">clone</a> of
   <var>original start node</var>.

   <li>Set the <a for=CharacterData>data</a> of
   <var>clone</var> to the result of
   <a lt="substring data">substringing data</a> with node
   <var>original start node</var>, offset
   <var>original start offset</var>, and count
   <var>original end offset</var> minus
   <var>original start offset</var>.

   <li><a>Append</a> <var>clone</var>
   to <var>fragment</var>.

   <li><a>Replace data</a> with node
   <var>original start node</var>, offset
   <var>original start offset</var>, count
   <var>original end offset</var> minus
   <var>original start offset</var>, and data the empty string.

   <li>Return <var>fragment</var>.
  </ol>

 <li>Let <var>common ancestor</var> be
 <var>original start node</var>.

 <li>While <var>common ancestor</var> is not an
 <a for=tree>inclusive ancestor</a> of
 <var>original end node</var>, set <var>common ancestor</var> to
 its own <a for=tree>parent</a>.

 <li>Let <var>first partially contained child</var> be null.

 <li>If <var>original start node</var> is <em>not</em> an
 <a for=tree>inclusive ancestor</a> of
 <var>original end node</var>, set <var>first partially contained child</var>
 to the first <a for=tree>child</a> of
 <var>common ancestor</var> that is <a for="live range">partially contained</a> in
 <var>range</var>.

 <li>Let <var>last partially contained child</var> be null.

 <li>
  If <var>original end node</var> is <em>not</em> an
  <a for=tree>inclusive ancestor</a> of
  <var>original start node</var>, set
  <var>last partially contained child</var> to the last
  <a for=tree>child</a> of <var>common ancestor</var> that is
  <a for="live range">partially contained</a> in <var>range</var>.

  <p class="note no-backref">These variable assignments do actually always make sense.
  For instance, if <var>original start node</var> is not an
  <a for=tree>inclusive ancestor</a> of
  <var>original end node</var>, <var>original start node</var> is itself
  <a for="live range">partially contained</a> in <var>range</var>, and so are all its
  <a>ancestors</a> up until a
  <a for=tree>child</a> of <var>common ancestor</var>.
  <var>common ancestor</var> cannot be <var>original start node</var>, because
  it has to be an <a for=tree>inclusive ancestor</a> of
  <var>original end node</var>. The other case is similar. Also, notice that the two
  <a>children</a> will never be equal if both are defined.

 <li>Let <var>contained children</var> be a list of all
 <a>children</a> of
 <var>common ancestor</var> that are <a for="live range">contained</a> in
 <var>range</var>, in <a>tree order</a>.

 <li>
  <p>If any member of <var>contained children</var> is a <a>doctype</a>, then <a>throw</a> a
  "{{HierarchyRequestError!!exception}}" {{DOMException}}.
  <!-- Firefox 4.0 actually removes the non-DocumentType nodes before
  throwing the exception. Opera 11.00 removes the DocumentType too, and
  doesn't throw. I go with IE9 and Chrome 12 dev, which don't remove any
  nodes. DOM 2 Range doesn't specify what exactly happens here, except that
  an exception should be thrown. -->

  <p class="note no-backref">We do not have to worry about the first or last partially
  contained node, because a <a>doctype</a> can never be
  partially contained. It cannot be a boundary point of a range, and it
  cannot be the ancestor of anything.

 <li>If <var>original start node</var> is an
 <a for=tree>inclusive ancestor</a> of
 <var>original end node</var>, set <var>new node</var> to
 <var>original start node</var> and <var>new offset</var> to
 <var>original start offset</var>.

 <li>
  Otherwise:
  <ol>
   <li>Let <var>reference node</var> equal <var>original start node</var>.

   <li>While <var>reference node</var>'s
   <a for=tree>parent</a> is not null and is not an
   <a for=tree>inclusive ancestor</a> of
   <var>original end node</var>, set <var>reference node</var> to its
   <a for=tree>parent</a>.

   <li>
    Set <var>new node</var> to the
    <a for=tree>parent</a> of <var>reference node</var>, and
    <var>new offset</var> to one plus <var>reference node</var>'s
    <a for=tree>index</a>.

    <p class="note no-backref">If <var>reference node</var>'s
    <a for=tree>parent</a> is null, it would be the
    <a for="live range">root</a> of <var>range</var>, so would be an
    <a for=tree>inclusive ancestor</a> of
    <var>original end node</var>, and we could not reach this point.
  </ol>

  <!-- Now we start with mutations, so we can't refer to the context object
  anymore unless we carefully consider how it will have mutated. -->

 <li>
  If <var>first partially contained child</var> is a
  {{Text}}, {{ProcessingInstruction}}, or
  {{Comment}} <a>node</a>:

  <p class="note no-backref">In this case, <var>first partially contained child</var> is
  <var>original start node</var>.

  <ol>
   <li>Let <var>clone</var> be a
   <a lt="clone a node">clone</a> of
   <var>original start node</var>.

   <li>Set the <a for=CharacterData>data</a> of
   <var>clone</var> to the result of
   <a lt="substring data">substringing data</a> with node
   <var>original start node</var>, offset
   <var>original start offset</var>, and count
   <var>original start node</var>'s
   <a>length</a> minus
   <var>original start offset</var>.

   <li><a>Append</a> <var>clone</var>
   to <var>fragment</var>.

   <li><a>Replace data</a> with node
   <var>original start node</var>, offset
   <var>original start offset</var>, count
   <var>original start node</var>'s
   <a>length</a> minus
   <var>original start offset</var>, and data the empty string.
  </ol>

 <li>
  Otherwise, if <var>first partially contained child</var> is not
  null:

  <ol>
   <li>Let <var>clone</var> be a
   <a lt="clone a node">clone</a> of
   <var>first partially contained child</var>.

   <li><a>Append</a> <var>clone</var>
   to <var>fragment</var>.

   <li>Let <var>subrange</var> be a new <a>live range</a>
   whose <a for=range>start</a> is
   (<var>original start node</var>, <var>original start offset</var>) and
   whose <a for=range>end</a> is
   (<var>first partially contained child</var>, <var>first partially contained child</var>'s <a>length</a>).

   <li><p>Let <var>subfragment</var> be the result of <a for="live range">extracting</a>
   <var>subrange</var>.

   <li><a>Append</a> <var>subfragment</var> to
   <var>clone</var>.
  </ol>

 <li>For each <var>contained child</var> in <var>contained children</var>,
 <a>append</a> <var>contained child</var> to
 <var>fragment</var>.

 <li>
  If <var>last partially contained child</var> is a
  {{Text}}, {{ProcessingInstruction}}, or
  {{Comment}} <a>node</a>:

  <p class="note no-backref">In this case, <var>last partially contained child</var> is
  <var>original end node</var>.

  <ol>
   <li>Let <var>clone</var> be a <a lt="clone a node">clone</a> of
   <var>original end node</var>.

   <li>Set the <a for=CharacterData>data</a> of
   <var>clone</var> to the result of
   <a lt="substring data">substringing data</a> with node
   <var>original end node</var>, offset 0, and count
   <var>original end offset</var>.

   <li><a>Append</a> <var>clone</var>
   to <var>fragment</var>.

   <li><a>Replace data</a> with node
   <var>original end node</var>, offset 0, count
   <var>original end offset</var>, and data the empty string.
  </ol>

 <li>
  Otherwise, if <var>last partially contained child</var> is not
  null:

  <ol>
   <li>Let <var>clone</var> be a
   <a lt="clone a node">clone</a> of
   <var>last partially contained child</var>.

   <li><a>Append</a> <var>clone</var>
   to <var>fragment</var>.

   <li>Let <var>subrange</var> be a new <a>live range</a>
   whose <a for=range>start</a> is
   (<var>last partially contained child</var>, 0) and whose
   <a for=range>end</a> is
   (<var>original end node</var>, <var>original end offset</var>).

   <li><p>Let <var>subfragment</var> be the result of <a for="live range">extracting</a>
   <var>subrange</var>.

   <li><a>Append</a> <var>subfragment</var> to
   <var>clone</var>.
  </ol>

 <li>Set <var>range</var>'s <a for=range>start</a> and
 <a for=range>end</a> to
 (<var>new node</var>, <var>new offset</var>).

 <li>Return <var>fragment</var>.
</ol>

<p>The <dfn method for=Range><code>extractContents()</code></dfn> method, when invoked, must return
the result of <a for="live range">extracting</a> the <a>context object</a>.

<p>To
<dfn export id=concept-range-clone for="live range" lt="clone the contents|cloning the contents">clone the contents</dfn>
of a <a>live range</a> <var>range</var>, run these steps:

<ol>
 <li><p>Let <var>fragment</var> be a new {{DocumentFragment}} <a for=/>node</a> whose
 <a for=Node>node document</a> is <var>range</var>'s <a for=range>start node</a>'s
 <a for=Node>node document</a>.

 <li><p>If <var>range</var> is <a for=range>collapsed</a>, then return <var>fragment</var>.
 <!-- This is only really needed when the start and end nodes are
 text/comment, to avoid creating an empty clone as the child of the
 fragment. (Opera 11 actually does include such an empty clone, it seems,
 but Gecko and WebKit do not as of March 2011, so we follow them.)
 Otherwise, the following steps are all no-ops. But it's simplest to include
 this step anyway. -->

 <li>Let <var>original start node</var>, <var>original start offset</var>,
 <var>original end node</var>, and <var>original end offset</var> be
 <var>range</var>'s <a for=range>start node</a>,
 <a for=range>start offset</a>,
 <a for=range>end node</a>, and
 <a for=range>end offset</a>, respectively.

 <li>
  If <var>original start node</var> is <var>original end node</var>, and they are a
  {{Text}}, {{ProcessingInstruction}}, or {{Comment}} <a>node</a>:

  <ol>
   <li>Let <var>clone</var> be a <a lt="clone a node">clone</a> of
   <var>original start node</var>.

   <li>Set the <a for=CharacterData>data</a> of
   <var>clone</var> to the result of
   <a lt="substring data">substringing data</a> with node
   <var>original start node</var>, offset
   <var>original start offset</var>, and count
   <var>original end offset</var> minus
   <var>original start offset</var>.

   <li><a>Append</a> <var>clone</var>
   to <var>fragment</var>.

   <li>Return <var>fragment</var>.
  </ol>

 <li>Let <var>common ancestor</var> be
 <var>original start node</var>.

 <li>While <var>common ancestor</var> is not an
 <a for=tree>inclusive ancestor</a> of
 <var>original end node</var>, set
 <var>common ancestor</var> to its own
 <a for=tree>parent</a>.

 <li>Let <var>first partially contained child</var> be null.

 <li>If <var>original start node</var> is <em>not</em> an
 <a for=tree>inclusive ancestor</a> of
 <var>original end node</var>, set <var>first partially contained child</var>
 to the first <a for=tree>child</a> of
 <var>common ancestor</var> that is <a for="live range">partially contained</a> in
 <var>range</var>.

 <li>Let <var>last partially contained child</var> be null.

 <li>
  If <var>original end node</var> is <em>not</em> an
  <a for=tree>inclusive ancestor</a> of
  <var>original start node</var>, set
  <var>last partially contained child</var> to the last
  <a for=tree>child</a> of <var>common ancestor</var> that is
  <a for="live range">partially contained</a> in <var>range</var>.

  <p class="note no-backref">These variable assignments do actually always make sense.
  For instance, if <var>original start node</var> is not an
  <a for=tree>inclusive ancestor</a> of
  <var>original end node</var>, <var>original start node</var> is itself
  <a for="live range">partially contained</a> in <var>range</var>, and so are all its
  <a>ancestors</a> up until a
  <a for=tree>child</a> of <var>common ancestor</var>.
  <var>common ancestor</var> cannot be <var>original start node</var>, because
  it has to be an <a for=tree>inclusive ancestor</a> of
  <var>original end node</var>. The other case is similar. Also, notice that the two
  <a>children</a> will never be equal if both are defined.

 <li>Let <var>contained children</var> be a list of all
 <a>children</a> of
 <var>common ancestor</var> that are <a for="live range">contained</a> in
 <var>range</var>, in <a>tree order</a>.

 <li>
  <p>If any member of <var>contained children</var> is a <a>doctype</a>, then <a>throw</a> a
  "{{HierarchyRequestError!!exception}}" {{DOMException}}.

  <p class="note no-backref">We do not have to worry about the first or last partially
  contained node, because a <a>doctype</a> can never be
  partially contained. It cannot be a boundary point of a range, and it
  cannot be the ancestor of anything.

 <li>
  If <var>first partially contained child</var> is a
  {{Text}}, {{ProcessingInstruction}}, or
  {{Comment}} <a>node</a>:

  <p class="note no-backref">In this case, <var>first partially contained child</var> is
  <var>original start node</var>.

  <ol>
   <li>Let <var>clone</var> be a
   <a lt="clone a node">clone</a> of
   <var>original start node</var>.

   <li>Set the <a for=CharacterData>data</a> of
   <var>clone</var> to the result of
   <a lt="substring data">substringing data</a> with node
   <var>original start node</var>, offset
   <var>original start offset</var>, and count
   <var>original start node</var>'s
   <a>length</a> minus
   <var>original start offset</var>.

   <li><a>Append</a> <var>clone</var>
   to <var>fragment</var>.
  </ol>

 <li>
  Otherwise, if <var>first partially contained child</var> is not
  null:

  <ol>
   <li>Let <var>clone</var> be a
   <a lt="clone a node">clone</a> of
   <var>first partially contained child</var>.

   <li><a>Append</a> <var>clone</var>
   to <var>fragment</var>.

   <li>Let <var>subrange</var> be a new <a>live range</a>
   whose <a for=range>start</a> is
   (<var>original start node</var>, <var>original start offset</var>) and
   whose <a for=range>end</a> is
   (<var>first partially contained child</var>, <var>first partially contained child</var>'s <a>length</a>).

   <li><p>Let <var>subfragment</var> be the result of <a for="live range">cloning the contents</a>
   of <var>subrange</var>.

   <li><a>Append</a> <var>subfragment</var> to
   <var>clone</var>.
  </ol>

 <li>
  For each <var>contained child</var> in
  <var>contained children</var>:

  <ol>
   <li>Let <var>clone</var> be a <a lt="clone a node">clone</a> of
   <var>contained child</var> with the <i>clone children flag</i> set.

   <li><a>Append</a> <var>clone</var> to
   <var>fragment</var>.
  </ol>

 <li>
  If <var>last partially contained child</var> is a
  {{Text}}, {{ProcessingInstruction}}, or
  {{Comment}} <a>node</a>:

  <p class="note no-backref">In this case, <var>last partially contained child</var> is
  <var>original end node</var>.

  <ol>
   <li>Let <var>clone</var> be a <a lt="clone a node">clone</a> of
   <var>original end node</var>.

   <li>Set the <a for=CharacterData>data</a> of
   <var>clone</var> to the result of
   <a lt="substring data">substringing data</a> with node
   <var>original end node</var>, offset 0, and count
   <var>original end offset</var>.

   <li><a>Append</a> <var>clone</var> to
   <var>fragment</var>.
  </ol>

 <li>
  Otherwise, if <var>last partially contained child</var> is not
  null:

  <ol>
   <li>Let <var>clone</var> be a
   <a lt="clone a node">clone</a> of
   <var>last partially contained child</var>.

   <li><a>Append</a> <var>clone</var>
   to <var>fragment</var>.

   <li>Let <var>subrange</var> be a new <a>live range</a>
   whose <a for=range>start</a> is
   (<var>last partially contained child</var>, 0) and whose
   <a for=range>end</a> is
   (<var>original end node</var>, <var>original end offset</var>).

   <li><p>Let <var>subfragment</var> be the result of <a for="live range">cloning the contents</a>
   of <var>subrange</var>.

   <li><a>Append</a> <var>subfragment</var> to
   <var>clone</var>.
  </ol>

 <li>Return <var>fragment</var>.
</ol>

<p>The <dfn method for=Range><code>cloneContents()</code></dfn> method, when invoked, must return
the result of <a for="live range">cloning the contents</a> of the <a>context object</a>.

<p>To <dfn export id=concept-range-insert for="live range">insert</dfn> a <a for=/>node</a>
<var>node</var> into a <a>live range</a> <var>range</var>, run these steps:

<ol>
 <li>If <var>range</var>'s <a for=range>start node</a> is a {{ProcessingInstruction}} or {{Comment}}
 <a>node</a>, is a {{Text}} <a>node</a> whose <a for=tree>parent</a> is null, or is <var>node</var>,
 then <a>throw</a> a "{{HierarchyRequestError!!exception}}" {{DOMException}}.

 <!--
 Behavior for Text node with null parent:

 IE9: Allows it to go through, resulting in the text/comment node having a non-null previousSibling but a null parentNode. (?!)
 Firefox 4.0: Throws non-standard exception
 Chrome 12 dev: Throws "HierarchyRequestError"
 Opera 11.00: Doesn't come up, doesn't allow ranges on detached nodes

 IE is clearly crazy, and non-standard exceptions are no good, so we go with
 WebKit.

 For a Comment node, see https://www.w3.org/Bugs/Public/show_bug.cgi?id=15350.
 IE9, Firefox 12.0a1, and Chrome 17 dev all agree on throwing a
 HierarchyRequestError.  Opera Next 12.00 alpha splits the comment, same as a
 text node.
 -->
 <li>Let <var>referenceNode</var> be null.

 <li>If <var>range</var>'s <a for=range>start node</a>
 is a {{Text}} <a>node</a>,
 set <var>referenceNode</var> to that {{Text}}
 <a>node</a>. <!-- This will change when we split
 it. -->

 <li>Otherwise, set <var>referenceNode</var> to the
 <a for=tree>child</a> of
 <a for=range>start node</a> whose
 <a for=tree>index</a> is
 <a for=range>start offset</a>, and null if
 there is no such <a for=tree>child</a>.

 <li>Let <var>parent</var> be <var>range</var>'s
 <a for=range>start node</a> if <var>referenceNode</var>
 is null, and <var>referenceNode</var>'s
 <a for=tree>parent</a> otherwise.

 <!-- IE9 and Chrome 12 dev throw an exception before splitting the text
 node if the insertBefore() is going to throw an exception (at least if the
 new node is the parent of the start node, for instance). Firefox 4.0 and
 Opera 11.00 don't.  Now that we have "ensure pre-insertion validity," we go
 with the IE/Chrome behavior because it's more correct.

 IE9 doesn't call splitText() if the offset is 0. This makes sense, but I go
 with what all other browsers do. -->
 <li><a>Ensure pre-insertion validity</a>
 of <var>node</var> into <var>parent</var> before
 <var>referenceNode</var>.

 <li>If <var>range</var>'s <a for=range>start node</a> is a {{Text}} <a>node</a>, set
 <var>referenceNode</var> to the result of <a lt="split a Text node">splitting</a> it with
 offset <var>range</var>'s <a for=range>start offset</a>.

 <li>If <var>node</var> is <var>referenceNode</var>, set <var>referenceNode</var> to its
 <a for=tree>next sibling</a>.
 <!-- Because we're about to remove node from its parent. -->

 <li><p>If <var>node</var>'s <a for=tree>parent</a> is non-null, then <a for=/>remove</a>
 <var>node</var>.

 <!-- Browsers disagree on how to handle the case where the range is
 collapsed: do you increment the end offset so the node is now included, or
 not?  DOM 2 Range says no, and Firefox 12.0a1 follows that, but IE9, Chrome
 17 dev, and Opera Next 12.00 alpha all do increment.  Apparently this
 traces back to Acid3 at one point requiring the non-standard behavior.
 Previously the spec matched DOM 2 Range, but it changed to match the
 majority of browsers.  See
 https://www.w3.org/Bugs/Public/show_bug.cgi?id=15297.

 We have to be careful here, because if node is a DocumentFragment, we might
 have inserted any number of nodes, including zero.  One corner case is if
 we insert an empty DocumentFragment and the range is collapsed in a text
 node.  In that case, the text node gets split, but browsers disagree on
 what to do with the range's end.  IE9 leaves it in place; Chrome 17 dev
 moves it to the parent element, before the reference node; Opera Next 12.00
 alpha moves it to the beginning of the new text node.  The spec follows
 WebKit just because it happens to be easier for me to spec.

 The logic for how much to increment the position by is copied from the
 "insert" algorithm.  Getting the new offset right was surprisingly tricky.
 -->
 <li>Let <var>newOffset</var> be <var>parent</var>'s
 <a>length</a> if <var>referenceNode</var> is null,
 and <var>referenceNode</var>'s <a for=tree>index</a>
 otherwise.

 <li>Increase <var>newOffset</var> by <var>node</var>'s
 <a>length</a> if <var>node</var> is a
 {{DocumentFragment}} <a>node</a>, and one otherwise.

 <li><a>Pre-insert</a>
 <var>node</var> into <var>parent</var> before <var>referenceNode</var>.

 <li><p>If <var>range</var> is <a for=range>collapsed</a>, then set <var>range</var>'s
 <a for=range>end</a> to (<var>parent</var>, <var>newOffset</var>).
</ol>

<p>The <dfn method for=Range><code>insertNode(<var>node</var>)</code></dfn> method, when invoked,
must <a for="live range">insert</a> <var>node</var> into the <a>context object</a>.

<p>The <dfn method for=Range><code>surroundContents(<var>newParent</var>)</code></dfn> method, when
invoked, must run these steps:

<!--
IE9 and Chrome 12 dev throw exceptions before doing any DOM mutations in at
least some cases, so they don't wind up modifying the DOM halfway. Like if you
try surrounding a selection with an ancestor. As with insertNode(), this is
slightly nicer, but Firefox 4.0 and Opera 11.00 don't do this, and their
behavior is slightly easier to spec, so I go with them for exceptions that are
thrown by things we call, like insertNode(). However, for
BAD_BOUNDARYPOINTS_ERR/INVALID_NODE_TYPE_ERR that we throw ourselves, I do the
check first thing, which matches everyone but Firefox.
-->

<ol>
 <li><p>If a non-{{Text}} <a>node</a> is <a for="live range">partially contained</a> in the
 <a>context object</a>, then <a>throw</a> an "{{InvalidStateError!!exception}}" {{DOMException}}.
 <!-- XXX Could we rephrase this condition to be more algorithmic and less
 declarative?-->

 <li>
  <p>If <var>newParent</var> is a {{Document}}, {{DocumentType}}, or {{DocumentFragment}}
  <a for=/>node</a>, then <a>throw</a> an "{{InvalidNodeTypeError!!exception}}" {{DOMException}}.

  <p class=note>For historical reasons {{Text}}, {{ProcessingInstruction}}, and {{Comment}}
  <a for=/>nodes</a> are not checked here and end up throwing later on as a side effect.

 <li><p>Let <var>fragment</var> be the result of <a lt="live range">extracting</a> the
 <a>context object</a>.
 <!-- If the range contains a DocumentType, Firefox 4.0 and Opera 11.00 don't
 immediately throw here. Firefox removes the non-DocumentType nodes and
 throws, Opera removes all nodes and doesn't throw. This applies to
 extractContents() proper, and also affects surroundContents(). I match DOM 2
 Range, IE9, and Chrome 12 dev. -->

 <li><p>If <var>newParent</var> has <a>children</a>, then <a for=Node>replace all</a> with null
 within <var>newParent</var>.

 <li><p><a for="live range">Insert</a> <var>newParent</var> into the <a>context object</a>.

 <li><p><a>Append</a> <var>fragment</var> to <var>newParent</var>.

 <li><p><a for=range>Select</a> <var>newParent</var> within the <a>context object</a>.
 <!-- Generally this isn't needed, because insertNode() will already do it,
 but it makes a difference in at least one corner case (when the original
 range lies in a single text node). -->
</ol>

<p>The <dfn method for=Range><code>cloneRange()</code></dfn> method, when invoked, must return a new
<a>live range</a> with the same <a for=range>start</a> and <a for=range>end</a> as the
<a>context object</a>.

<p>The <dfn method for=Range><code>detach()</code></dfn> method, when invoked, must do nothing.
<span class=note>Its functionality (disabling a {{Range}} object) was removed, but the method itself
is preserved for compatibility.</span>

<hr>

<dl class=domintro>
 <dt><var ignore>position</var> = <var>range</var> . {{Range/comparePoint(node, offset)}}
 <dd>Returns &minus;1 if the point is before the range, 0 if the point is
 in the range, and 1 if the point is after the range.

 <dt><var ignore>intersects</var> = <var>range</var> . {{Range/intersectsNode(node)}}
 <dd>Returns whether <var>range</var> intersects
 <var>node</var>.
</dl>

<div class=impl>

<p>The <dfn method for=Range><code>isPointInRange(<var>node</var>, <var>offset</var>)</code></dfn>
method, when invoked, must run these steps:
<!-- Tested October 2011 on Firefox 9.0a2 and Chrome 16 dev.  IE9 and Opera
11.50 don't support the method. -->

<ol>
 <li>If <var>node</var>'s <a for=tree>root</a> is
 different from the <a>context object</a>'s <a for="live range">root</a>, return false.
 <!-- This happens even if the offset is negative or too large, or if the node
 is a doctype, in both Firefox 9.0a2 and Chrome 16 dev. -->

 <li>If <var>node</var> is a <a>doctype</a>, then <a>throw</a> an
 "{{InvalidNodeTypeError!!exception}}" {{DOMException}}.
 <!-- Firefox 9.0a2 doesn't throw.  It ignores the offset and returns true or
 false depending on whether the doctype itself is in the range.  This makes
 some sense, but it doesn't match how other Range APIs handle doctypes, and
 having the second argument mandatory but ignored is just weird.  Thus I go
 with Chrome 16 dev, although I can see the merit in how Gecko works here. -->

 <li>If <var>offset</var> is greater than <var>node</var>'s <a>length</a>, then <a>throw</a> an
 "{{IndexSizeError!!exception}}" {{DOMException}}.
 <!-- Firefox 9.0a2 doesn't throw.  It seems to return true if the node is
 completely contained in the range, like with selectNode(), and false otherwise -
 even if all boundary points in the node are contained in the range, like
 with selectNodeContents().  This is weird, and inconsistent with other Range
 APIs, so I go with Chrome 16 dev.  This is probably an authoring bug, so it's
 best to throw anyway. -->

 <li>If (<var>node</var>, <var>offset</var>) is
 <a for="boundary point">before</a>
 <a for=range>start</a> or
 <a for="boundary point">after</a>
 <a for=range>end</a>, return false.

 <li>Return true.
</ol>

<p>The <dfn method for=Range><code>comparePoint(<var>node</var>, <var>offset</var>)</code></dfn>
method, when invoked, must run these steps:
<!-- IE9 doesn't support this method at all.  Firefox 12.0a1, Chrome 17 dev,
and Opera Next 12.00 alpha all do. -->

<ol>
 <li>If <var>node</var>'s <a for=tree>root</a> is different from the <a>context object</a>'s
 <a for="live range">root</a>, then <a>throw</a> a "{{WrongDocumentError!!exception}}" {{DOMException}}.
 <!-- Opera Next 12.00 alpha seems to return -1 in this case.  The spec matches
 Firefox 12.0a1 and Chrome 17 dev. -->

 <li>If <var>node</var> is a <a>doctype</a>, then <a>throw</a> an
 "{{InvalidNodeTypeError!!exception}}" {{DOMException}}.
 <!-- This matches Chrome 17 dev instead of Firefox 12.0a1 and Opera Next 12.00
 alpha, which don't throw and seem to just ignore the offset instead.  See
 comment for isPointInRange(). -->

 <li>If <var>offset</var> is greater than <var>node</var>'s <a>length</a>, then <a>throw</a> an
 "{{IndexSizeError!!exception}}" {{DOMException}}.
 <!-- This matches Chrome 17 dev instead of Firefox 12.0a1 and Opera Next 12.00
 alpha, which don't throw.  See comment for isPointInRange(). -->

 <li>If (<var>node</var>, <var>offset</var>) is
 <a for="boundary point">before</a>
 <a for=range>start</a>, return &minus;1.

 <li>If (<var>node</var>, <var>offset</var>) is
 <a for="boundary point">after</a>
 <a for=range>end</a>, return 1.

 <li>Return 0.
</ol>

<hr>

<p>The <dfn method for=Range><code>intersectsNode(<var>node</var>)</code></dfn> method, when
invoked, must run these steps:
<!-- Supported by Chrome 17 dev and Opera Next 12.00 alpha, but not IE9 or
Firefox 12.0a1. -->

<ol>
 <li>If <var>node</var>'s <a for=tree>root</a>
 is different from the <a>context object</a>'s
 <a for="live range">root</a>, return false.
 <!-- It seems like for doctypes, Opera Next 12.00 alpha throws
 InvalidNodeTypeError instead of returning false.  The spec follows Chrome
 17 dev. -->

 <li>Let <var>parent</var> be <var>node</var>'s
 <a for=tree>parent</a>.

 <li>If <var>parent</var> is null, return true.
 <!-- browsers currently throw, but are willing to change
      https://www.w3.org/Bugs/Public/show_bug.cgi?id=16759 -->

 <li>Let <var>offset</var> be <var>node</var>'s
 <a for=tree>index</a>.

 <li>If (<var>parent</var>, <var>offset</var>) is
 <a for="boundary point">before</a>
 <a for=range>end</a> and (<var>parent</var>,
 <var>offset</var> plus 1) is
 <a for="boundary point">after</a>
 <a for=range>start</a>, return true.

 <li>Return false.
</ol>

</div>

<hr>

<p>The <dfn export for=Range id=dom-range-stringifier>stringification behavior</dfn> must run
these steps:

<ol>
 <li><p>Let <var>s</var> be the empty string.

 <li><p>If the <a>context object</a>'s <a for=range>start node</a> is the <a>context object</a>'s
 <a for=range>end node</a> and it is a {{Text}} <a>node</a>, then return the substring of that
 {{Text}} <a>node</a>'s <a for=CharacterData>data</a> beginning at the <a>context object</a>'s
 <a for=range>start offset</a> and ending at the <a>context object</a>'s
 <a for=range>end offset</a>.

 <li><p>If the <a>context object</a>'s <a for=range>start node</a> is a {{Text}} <a>node</a>, then
 append the substring of that <a>node</a>'s <a for=CharacterData>data</a> from the
 <a>context object</a>'s <a for=range>start offset</a> until the end to <var>s</var>.

 <li><p>Append the <a for=string>concatenation</a> of the <a for=CharacterData>data</a> of all
 {{Text}} <a for=/>nodes</a> that are <a for="live range">contained</a> in the
 <a>context object</a>, in <a>tree order</a>, to <var>s</var>.

 <li><p>If the <a>context object</a>'s <a for=range>end node</a> is a {{Text}} <a>node</a>, then
 append the substring of that <a>node</a>'s <a for=CharacterData>data</a> from its start until the
 <a>context object</a>'s <a for=range>end offset</a> to <var>s</var>.

 <li><p>Return <var>s</var>.
</ol>

<hr>

<p class="note no-backref">The {{createContextualFragment()}}, {{Range/getClientRects()}},
and {{Range/getBoundingClientRect()}} methods are defined in other specifications.
[[DOM-Parsing]]
[[CSSOM-VIEW]]



<h2 id="traversal">Traversal</h2>

<p>{{NodeIterator}} and {{TreeWalker}} objects can be used to filter and traverse <a for=/>node</a>
<a>trees</a>.

<p>Each {{NodeIterator}} and {{TreeWalker}} object has an associated
<dfn noexport id=concept-traversal-active for=traversal>active flag</dfn> to avoid recursive
invocations. It is initially unset.

<p>Each {{NodeIterator}} and {{TreeWalker}} object also has an associated
<dfn noexport id=concept-traversal-root for=traversal>root</dfn> (a <a for=/>node</a>), a
<dfn noexport id=concept-traversal-whattoshow for=traversal>whatToShow</dfn> (a bitmask), and a
<dfn noexport id=concept-traversal-filter for=traversal>filter</dfn> (a callback).

<p>To <dfn noexport id=concept-node-filter>filter</dfn> a <a for=/>node</a> <var>node</var> within
a {{NodeIterator}} or {{TreeWalker}} object <var>traverser</var>, run these steps:

<ol>
 <li><p>If <var>traverser</var>'s <a for=traversal>active flag</a> is set, then throw an
 "{{InvalidStateError!!exception}}" {{DOMException}}.

 <li><p>Let <var>n</var> be <var>node</var>'s {{Node/nodeType}} attribute value &minus; 1.

 <li><p>If the <var>n</var><sup>th</sup> bit (where 0 is the least significant bit) of
 <var>traverser</var>'s <a for=traversal>whatToShow</a> is not set, then return
 {{NodeFilter/FILTER_SKIP}}.
 <!-- !((1 << (node.nodeType - 1)) & whatToShow) -->

 <li><p>If <var>traverser</var>'s <a for=traversal>filter</a> is null, then return
 {{NodeFilter/FILTER_ACCEPT}}.

 <li><p>Set <var>traverser</var>'s <a for=traversal>active flag</a>.

 <li><p>Let <var>result</var> be the return value of <a>call a user object's operation</a> with
 <var>traverser</var>'s <a for=traversal>filter</a>, "<code>acceptNode</code>", and
 « <var>node</var> ». If this throws an exception, then unset <var>traverser</var>'s
 <a for=traversal>active flag</a> and rethrow the exception.

 <li><p>Unset <var>traverser</var>'s <a for=traversal>active flag</a>.

 <li><p>Return <var>result</var>.
</ol>


<h3 id="interface-nodeiterator">Interface {{NodeIterator}}</h3>

<pre class=idl>
[Exposed=Window]
interface NodeIterator {
  [SameObject] readonly attribute Node root;
  readonly attribute Node referenceNode;
  readonly attribute boolean pointerBeforeReferenceNode;
  readonly attribute unsigned long whatToShow;
  readonly attribute NodeFilter? filter;

  Node? nextNode();
  Node? previousNode();

  void detach();
};
</pre>

<p class="note no-backref">{{NodeIterator}} objects can be created using the
{{createNodeIterator()}} method on {{Document}} objects.

<p>Each {{NodeIterator}} object has an associated
<dfn noexport for=NodeIterator id="iterator-collection">iterator collection</dfn>, which is a
<a for=/>collection</a> rooted at the {{NodeIterator}} object's <a for=traversal>root</a>, whose
filter matches any <a for=/>node</a>.

<p>Each {{NodeIterator}} object also has an associated <dfn for=NodeIterator>reference</dfn> (a
<a for=/>node</a>) and <dfn for=NodeIterator>pointer before reference</dfn> (a boolean).

<p class="note no-backref">As mentioned earlier, {{NodeIterator}} objects have an associated
<a for=traversal>active flag</a>, <a for=traversal>root</a>, <a for=traversal>whatToShow</a>, and
<a for=traversal>filter</a> as well.

<p>The <dfn><code>NodeIterator</code> pre-removing steps</dfn> given a <var>nodeIterator</var> and
<var>toBeRemovedNode</var>, are as follows:

<ol>
 <li><p>If <var>toBeRemovedNode</var> is not an <a for=tree>inclusive ancestor</a> of
 <var>nodeIterator</var>'s <a for=NodeIterator>reference</a>, or <var>toBeRemovedNode</var> is
 <var>nodeIterator</var>'s <a for=traversal>root</a>, then return.

 <li>
  <p>If <var>nodeIterator</var>'s <a for=NodeIterator>pointer before reference</a> is true, then:

  <ol>
   <li><p>Let <var>next</var> be <var>toBeRemovedNode</var>'s first <a>following</a>
   <a>node</a> that is an <a>inclusive descendant</a> of <var>nodeIterator</var>'s
   <a for=traversal>root</a> and is not an <a>inclusive descendant</a> of
   <var>toBeRemovedNode</var>, and null if there is no such <a>node</a>.

   <li><p>If <var>next</var> is non-null, then set <var>nodeIterator</var>'s
   <a for=NodeIterator>reference</a> to <var>next</var> and return.

   <li>
    <p>Otherwise, set <var>nodeIterator</var>'s <a for=NodeIterator>pointer before reference</a> to
    false.

    <p class="note no-backref">Steps are not terminated here.
  </ol>

 <li><p>Set <var>nodeIterator</var>'s <a for=NodeIterator>reference</a> to
 <var>toBeRemovedNode</var>'s <a for=tree>parent</a>, if <var>toBeRemovedNode</var>'s
 <a>previous sibling</a> is null, and to the <a>inclusive descendant</a> of
 <var>toBeRemovedNode</var>'s <a>previous sibling</a> that appears last in <a>tree order</a>
 otherwise.
</ol>

<hr>

<p>The <dfn attribute for=NodeIterator><code>root</code></dfn> attribute's getter, when invoked,
must return the <a>context object</a>'s <a for=traversal>root</a>.

<p>The <dfn attribute for=NodeIterator><code>referenceNode</code></dfn> attribute's getter, when
invoked, must return the <a>context object</a>'s <a for=NodeIterator>reference</a>.

<p>The <dfn attribute for=NodeIterator><code>pointerBeforeReferenceNode</code></dfn> attribute's
getter, when invoked, must return the <a>context object</a>'s
<a for=NodeIterator>pointer before reference</a>.

<p>The <dfn attribute for=NodeIterator><code>whatToShow</code></dfn> attribute's getter, when
invoked, must return the <a>context object</a>'s <a for=traversal>whatToShow</a>.

<p>The <dfn attribute for=NodeIterator><code>filter</code></dfn> attribute's getter, when invoked,
must return the <a>context object</a>'s <a for=traversal>filter</a>.

<p>To <dfn export id=concept-nodeiterator-traverse for=NodeIterator>traverse</dfn>, given a
{{NodeIterator}} object <var>iterator</var> and a direction <var>direction</var>, run these steps:

<ol>
 <li><p>Let <var>node</var> be <var>iterator</var>'s <a for=NodeIterator>reference</a>.

 <li><p>Let <var>beforeNode</var> be <var>iterator</var>'s
 <a for=NodeIterator>pointer before reference</a>.

 <li>
  <p>While true:

  <ol>
   <li>
    <p>Branch on <var>direction</var>:

    <dl class=switch>
     <dt>next
     <dd>
      <p>If <var>beforeNode</var> is false, then set <var>node</var> to the first <a for=/>node</a>
      <a>following</a> <var>node</var> in <var>iterator</var>'s
      <a for=NodeIterator>iterator collection</a>. If there is no such <a for=/>node</a>, then
      return null.

      <p>If <var>beforeNode</var> is true, then set it to false.

     <dt>previous
     <dd>
      <p>If <var>beforeNode</var> is true, then set <var>node</var> to the first <a for=/>node</a>
      <a>preceding</a> <var>node</var> in <var>iterator</var>'s
      <a for=NodeIterator>iterator collection</a>. If there is no such <a for=/>node</a>, then
      return null.

      <p>If <var>beforeNode</var> is false, then set it to true.
    </dl>

   <li><p>Let <var>result</var> be the result of <a for=/>filtering</a> <var>node</var> within
   <var>iterator</var>.

   <li><p>If <var>result</var> is {{NodeFilter/FILTER_ACCEPT}}, then <a for=iteration>break</a>.
  </ol>

 <li><p>Set <var>iterator</var>'s <a for=NodeIterator>reference</a> to <var>node</var>.

 <li><p>Set <var>iterator</var>'s <a for=NodeIterator>pointer before reference</a> to
 <var>beforeNode</var>.

 <li><p>Return <var>node</var>.
</ol>

<p>The <dfn method for=NodeIterator><code>nextNode()</code></dfn> method, when invoked, must return
the result of <a for=NodeIterator>traversing</a> with the <a>context object</a> and next.

<p>The <dfn method for=NodeIterator><code>previousNode()</code></dfn> method, when invoked, must
return the result of <a for=NodeIterator>traversing</a> with the <a>context object</a> and previous.

<p>The <dfn method for=NodeIterator><code>detach()</code></dfn> method, when invoked, must do
nothing. <span class=note>Its functionality (disabling a {{NodeIterator}} object) was removed, but
the method itself is preserved for compatibility.</span>


<h3 id=interface-treewalker>Interface {{TreeWalker}}</h3>

<pre class=idl>
[Exposed=Window]
interface TreeWalker {
  [SameObject] readonly attribute Node root;
  readonly attribute unsigned long whatToShow;
  readonly attribute NodeFilter? filter;
           attribute Node currentNode;

  Node? parentNode();
  Node? firstChild();
  Node? lastChild();
  Node? previousSibling();
  Node? nextSibling();
  Node? previousNode();
  Node? nextNode();
};</pre>

<p class="note no-backref">{{TreeWalker}} objects can be created using the {{createTreeWalker()}}
method on {{Document}} objects.

<p>Each {{TreeWalker}} object has an associated <dfn for=TreeWalker>current</dfn> (a
<a for=/>node</a>).

<p class="note no-backref">As mentioned earlier {{TreeWalker}} objects have an associated
<a for=traversal>root</a>, <a for=traversal>whatToShow</a>, and <a for=traversal>filter</a> as well.

<p>The <dfn attribute for=TreeWalker><code>root</code></dfn> attribute's getter, when invoked, must
return the <a>context object</a>'s <a for=traversal>root</a>.

<p>The <dfn attribute for=TreeWalker><code>whatToShow</code></dfn> attribute's getter, when invoked,
must return the <a>context object</a>'s <a for=traversal>whatToShow</a>.

<p>The <dfn attribute for=TreeWalker><code>filter</code></dfn> attribute's getter, when invoked,
must return the <a>context object</a>'s <a for=traversal>filter</a>.

<p>The <dfn attribute for=TreeWalker><code>currentNode</code></dfn> attribute's getter, when
invoked, must return the <a>context object</a>'s <a for=TreeWalker>current</a>.

<p>The {{TreeWalker/currentNode}} attribute's setter, when invoked, must set the
<a>context object</a>'s <a for=TreeWalker>current</a> to the given value.

<hr>

<p>The <dfn method for=TreeWalker><code>parentNode()</code></dfn> method, when invoked, must run
these steps:

<ol>
 <li><p>Let <var>node</var> be the <a>context object</a>'s <a for=TreeWalker>current</a>.

 <li>
  <p>While <var>node</var> is non-null and is not the <a>context object</a>'s
  <a for=traversal>root</a>:

  <ol>
   <li><p>Set <var>node</var> to <var>node</var>'s <a for=tree>parent</a>.

   <li><p>If <var>node</var> is non-null and <a for=/>filtering</a> <var>node</var> within the
   <a>context object</a> returns {{NodeFilter/FILTER_ACCEPT}}, then set the <a>context object</a>'s
   <a for=TreeWalker>current</a> to <var>node</var> and return <var>node</var>.
  </ol>

 <li><p>Return null.
</ol>

<p>To <dfn noexport for=TreeWalker id=concept-traverse-children>traverse children</dfn>, given a
<var>walker</var> and <var>type</var>, run these steps:

<ol>
 <li><p>Let <var>node</var> be <var>walker</var>'s <a for=TreeWalker>current</a>.

 <li><p>Set <var>node</var> to <var>node</var>'s <a for=tree>first child</a> if <var>type</var> is
 first, and <var>node</var>'s <a for=tree>last child</a> if <var>type</var> is last.

 <li>
  <p>While <var>node</var> is non-null:

  <ol>
   <li><p>Let <var>result</var> be the result of <a for=/>filtering</a> <var>node</var> within
   <var>walker</var>.

   <li><p>If <var>result</var> is {{NodeFilter/FILTER_ACCEPT}}, then set <var>walker</var>'s
   <a for=TreeWalker>current</a> to <var>node</var> and return <var>node</var>.

   <li>
    <p>If <var>result</var> is {{NodeFilter/FILTER_SKIP}}, then:

    <ol>
     <li><p>Let <var>child</var> be <var>node</var>'s <a for=tree>first child</a> if <var>type</var>
     is first, and <var>node</var>'s <a for=tree>last child</a> if <var>type</var> is last.

     <li><p>If <var>child</var> is non-null, then set <var>node</var> to <var>child</var> and
     <a for=iteration>continue</a>.
    </ol>

   <li>
    <p>While <var>node</var> is non-null:

    <ol>
     <li><p>Let <var>sibling</var> be <var>node</var>'s <a for=tree>next sibling</a> if
     <var>type</var> is first, and <var>node</var>'s <a for=tree>previous sibling</a> if
     <var>type</var> is last.

     <li><p>If <var>sibling</var> is non-null, then set <var>node</var> to <var>sibling</var> and
     <a for=iteration>break</a>.

     <li><p>Let <var>parent</var> be <var>node</var>'s <a for=tree>parent</a>.

     <li><p>If <var>parent</var> is null, <var>walker</var>'s <a for=traversal>root</a>, or
     <var>walker</var>'s <a for=TreeWalker>current</a>, then return null.

     <li><p>Set <var>node</var> to <var>parent</var>.
    </ol>
  </ol>

 <li><p>Return null.
</ol>

<p>The <dfn method for=TreeWalker><code>firstChild()</code></dfn> method, when invoked, must
<a>traverse children</a> with the <a>context object</a> and first.

<p>The <dfn method for=TreeWalker><code>lastChild()</code></dfn> method, when invoked, must
<a>traverse children</a> with the <a>context object</a> and last.

<p>To <dfn noexport id=concept-traverse-siblings>traverse siblings</dfn>, given a <var>walker</var>
and <var>type</var>, run these steps:

<ol>
 <li><p>Let <var>node</var> be <var>walker</var>'s <a for=TreeWalker>current</a>.

 <li><p>If <var>node</var> is <a for=traversal>root</a>, then return null.

 <li>
  <p>While true:

  <ol>
   <li><p>Let <var>sibling</var> be <var>node</var>'s <a for=tree>next sibling</a> if
   <var>type</var> is next, and <var>node</var>'s <a for=tree>previous sibling</a> if
   <var>type</var> is previous.

   <li>
    <p>While <var>sibling</var> is non-null:

    <ol>
     <li><p>Set <var>node</var> to <var>sibling</var>.

     <li><p>Let <var>result</var> be the result of <a for=/>filtering</a> <var>node</var> within
     <var>walker</var>.

     <li><p>If <var>result</var> is {{NodeFilter/FILTER_ACCEPT}}, then set <var>walker</var>'s
     <a for=TreeWalker>current</a> to <var>node</var> and return <var>node</var>.

     <li><p>Set <var>sibling</var> to <var>node</var>'s <a for=tree>first child</a> if
     <var>type</var> is next, and <var>node</var>'s <a for=tree>last child</a> if <var>type</var> is
     previous.

     <li><p>If <var>result</var> is {{NodeFilter/FILTER_REJECT}} or <var>sibling</var> is null, then
     set <var>sibling</var> to <var>node</var>'s <a for=tree>next sibling</a> if <var>type</var> is
     next, and <var>node</var>'s <a for=tree>previous sibling</a> if <var>type</var> is previous.
    </ol>

   <li><p>Set <var>node</var> to <var>node</var>'s <a for=tree>parent</a>.

   <li><p>If <var>node</var> is null or <var>walker</var>'s <a for=traversal>root</a>, then return
   null.

   <li><p>If the return value of <a for=/>filtering</a> <var>node</var> within <var>walker</var> is
   {{NodeFilter/FILTER_ACCEPT}}, then return null.
  </ol>
</ol>

<p>The <dfn method for=TreeWalker><code>nextSibling()</code></dfn> method, when invoked, must
<a>traverse siblings</a> with the <a>context object</a> and next.

<p>The <dfn method for=TreeWalker><code>previousSibling()</code></dfn> method, when invoked, must
<a>traverse siblings</a> with the <a>context object</a> and previous.

<p>The <dfn method for=TreeWalker><code>previousNode()</code></dfn> method, when invoked, must run
these steps:

<ol>
 <li><p>Let <var>node</var> be the <a>context object</a>'s <a for=TreeWalker>current</a>.

 <li>
  <p>While <var>node</var> is not the <a>context object</a>'s <a for=traversal>root</a>:

  <ol>
   <li><p>Let <var>sibling</var> be <var>node</var>'s <a for=tree>previous sibling</a>.

   <li>
    <p>While <var>sibling</var> is non-null:

    <ol>
     <li><p>Set <var>node</var> to <var>sibling</var>.

     <li><p>Let <var>result</var> be the result of <a for=/>filtering</a> <var>node</var> within the
     <a>context object</a>.

     <li>
      <p>While <var>result</var> is not {{NodeFilter/FILTER_REJECT}} and <var>node</var> has a
      <a for=tree>child</a>:

      <ol>
       <li><p>Set <var>node</var> to <var>node</var>'s <a for=tree>last child</a>.

       <li><p>Set <var>result</var> to the result of <a for=/>filtering</a> <var>node</var> within
       the <a>context object</a>.
      </ol>

     <li><p>If <var>result</var> is {{NodeFilter/FILTER_ACCEPT}}, then set the
     <a>context object</a>'s <a for=TreeWalker>current</a> to <var>node</var> and return
     <var>node</var>.

     <li><p>Set <var>sibling</var> to <var>node</var>'s <a for=tree>previous sibling</a>.
    </ol>

   <li><p>If <var>node</var> is the <a>context object</a>'s <a for=traversal>root</a> or
   <var>node</var>'s <a for=tree>parent</a> is null, then return null.

   <li><p>Set <var>node</var> to <var>node</var>'s <a for=tree>parent</a>.

   <li><p>If the return value of <a for=/>filtering</a> <var>node</var> within the
   <a>context object</a> is {{NodeFilter/FILTER_ACCEPT}}, then set the <a>context object</a>'s
   <a for=TreeWalker>current</a> to <var>node</var> and return <var>node</var>.
  </ol>

 <li><p>Return null.
</ol>

<p>The <dfn method for=TreeWalker><code>nextNode()</code></dfn> method, when invoked, must run these
steps:

<ol>
 <li><p>Let <var>node</var> be the <a>context object</a>'s <a for=TreeWalker>current</a>.

 <li><p>Let <var>result</var> be {{NodeFilter/FILTER_ACCEPT}}.

 <li>
  <p>While true:

  <ol>
   <li>
    <p>While <var>result</var> is not {{NodeFilter/FILTER_REJECT}} and <var>node</var> has a
    <a for=tree>child</a>:

    <ol>
     <li><p>Set <var>node</var> to its <a for=tree>first child</a>.

     <li><p>Set <var>result</var> to the result of <a for=/>filtering</a> <var>node</var> within the
     <a>context object</a>.

     <li><p>If <var>result</var> is {{NodeFilter/FILTER_ACCEPT}}, then set the
     <a>context object</a>'s <a for=TreeWalker>current</a> to <var>node</var> and return
     <var>node</var>.
    </ol>

   <li><p>Let <var>sibling</var> be null.

   <li><p>Let <var>temporary</var> be <var>node</var>.

   <li>
    <p>While <var>temporary</var> is non-null:

    <ol>
     <li><p>If <var>temporary</var> is the <a>context object</a>'s <a for=traversal>root</a>, then
     return null.

     <li><p>Set <var>sibling</var> to <var>temporary</var>'s <a for=tree>next sibling</a>.

     <li><p>If <var>sibling</var> is non-null, then set <var>node</var> to <var>sibling</var> and
     <a for=iteration>break</a>.

     <li><p>Set <var>temporary</var> to <var>temporary</var>'s <a for=tree>parent</a>.
    </ol>

   <li><p>Set <var>result</var> to the result of <a for=/>filtering</a> <var>node</var> within the
   <a>context object</a>.

   <li><p>If <var>result</var> is {{NodeFilter/FILTER_ACCEPT}}, then set the <a>context object</a>'s
   <a for=TreeWalker>current</a> to <var>node</var> and return <var>node</var>.
  </ol>
</ol>


<h3 id="interface-nodefilter">Interface {{NodeFilter}}</h3>

<pre class=idl>
[Exposed=Window]
callback interface NodeFilter {
  // Constants for acceptNode()
  const unsigned short FILTER_ACCEPT = 1;
  const unsigned short FILTER_REJECT = 2;
  const unsigned short FILTER_SKIP = 3;

  // Constants for whatToShow
  const unsigned long SHOW_ALL = 0xFFFFFFFF;
  const unsigned long SHOW_ELEMENT = 0x1;
  const unsigned long SHOW_ATTRIBUTE = 0x2;
  const unsigned long SHOW_TEXT = 0x4;
  const unsigned long SHOW_CDATA_SECTION = 0x8;
  const unsigned long SHOW_ENTITY_REFERENCE = 0x10; // historical
  const unsigned long SHOW_ENTITY = 0x20; // historical
  const unsigned long SHOW_PROCESSING_INSTRUCTION = 0x40;
  const unsigned long SHOW_COMMENT = 0x80;
  const unsigned long SHOW_DOCUMENT = 0x100;
  const unsigned long SHOW_DOCUMENT_TYPE = 0x200;
  const unsigned long SHOW_DOCUMENT_FRAGMENT = 0x400;
  const unsigned long SHOW_NOTATION = 0x800; // historical

  unsigned short acceptNode(Node node);
};
</pre>

<p class="note no-backref">{{NodeFilter}} objects can be used as <a for=traversal>filter</a> for
{{NodeIterator}} and {{TreeWalker}} objects and also provide constants for their
<a for=traversal>whatToShow</a> bitmask. A {{NodeFilter}} object is typically implemented as a
JavaScript function.

<p>These constants can be used as <a for=traversal>filter</a> return value:

<ul class="brief">
 <li><dfn const for=NodeFilter><code>FILTER_ACCEPT</code></dfn> (1);
 <li><dfn const for=NodeFilter><code>FILTER_REJECT</code></dfn> (2);
 <li><dfn const for=NodeFilter><code>FILTER_SKIP</code></dfn> (3).
</ul>

<p>These constants can be used for <a for=traversal>whatToShow</a>:

<ul class="brief">
 <li><dfn const for=NodeFilter><code>SHOW_ALL</code></dfn> (4294967295, FFFFFFFF in hexadecimal);
 <li><dfn const for=NodeFilter><code>SHOW_ELEMENT</code></dfn> (1);
 <li><dfn const for=NodeFilter><code>SHOW_ATTRIBUTE</code></dfn> (2);
 <li><dfn const for=NodeFilter><code>SHOW_TEXT</code></dfn> (4);
 <li><dfn const for=NodeFilter><code>SHOW_CDATA_SECTION</code></dfn> (8);
 <li><dfn const for=NodeFilter><code>SHOW_PROCESSING_INSTRUCTION</code></dfn> (64, 40 in hexadecimal);
 <li><dfn const for=NodeFilter><code>SHOW_COMMENT</code></dfn> (128, 80 in hexadecimal);
 <li><dfn const for=NodeFilter><code>SHOW_DOCUMENT</code></dfn> (256, 100 in hexadecimal);
 <li><dfn const for=NodeFilter><code>SHOW_DOCUMENT_TYPE</code></dfn> (512, 200 in hexadecimal);
 <li><dfn const for=NodeFilter><code>SHOW_DOCUMENT_FRAGMENT</code></dfn> (1024, 400 in hexadecimal).
</ul>



<h2 id="sets">Sets</h2>

<p class="note no-backref">Yes, the name {{DOMTokenList}} is an unfortunate legacy mishap.

<h3 id="interface-domtokenlist">Interface {{DOMTokenList}}</h3>

<pre class="idl">
[Exposed=Window]
interface DOMTokenList {
  readonly attribute unsigned long length;
  getter DOMString? item(unsigned long index);
  boolean contains(DOMString token);
  [CEReactions] void add(DOMString... tokens);
  [CEReactions] void remove(DOMString... tokens);
  [CEReactions] boolean toggle(DOMString token, optional boolean force);
  [CEReactions] boolean replace(DOMString token, DOMString newToken);
  boolean supports(DOMString token);
  [CEReactions] stringifier attribute DOMString value;
  iterable&lt;DOMString>;
};
</pre>

<p>A {{DOMTokenList}} object has an associated
<dfn export id=concept-dtl-tokens for=DOMTokenList>token set</dfn> (a <a for=/>set</a>), which is
initially empty.

<p>A {{DOMTokenList}} object also has an associated <a for="/">element</a> and an <a>attribute</a>'s
<a for=Attr>local name</a>.

<a lt="Other applicable specifications">Specifications</a> may define
<dfn export for=Node id=concept-supported-tokens>supported tokens</dfn> for a {{DOMTokenList}}'s
associated <a>attribute</a>'s <a for=Attr>local name</a>.

<p>A {{DOMTokenList}} object's
<dfn export id=concept-domtokenlist-validation for=DOMTokenList>validation steps</dfn> for a given
<var>token</var> are:

<ol>
 <li><p>If the associated <a>attribute</a>'s <a for=Attr>local name</a> does not define
 <a for=Node>supported tokens</a>, <a>throw</a> a <code>TypeError</code>.

 <li><p>Let <var>lowercase token</var> be a copy of <var>token</var>, in <a>ASCII lowercase</a>.

 <li><p>If <var>lowercase token</var> is present in <a for=Node>supported tokens</a>, return true.

 <li><p>Return false.
</ol>

<p>A {{DOMTokenList}} object's <dfn id=concept-dtl-update for="DOMTokenList">update steps</dfn> are:

<ol>
 <li><p>If the associated <a for="/">element</a> does not have an associated <a>attribute</a> and
 <a>token set</a> is empty, then return.

 <li><p><a>Set an attribute value</a> for the associated <a for="/">element</a> using associated
 <a>attribute</a>'s <a for=Attr>local name</a> and the result of running the <a>ordered set
 serializer</a> for <a>token set</a>.
</ol>

<p>A {{DOMTokenList}} object's <dfn id=concept-dtl-serialize for=DOMTokenList>serialize steps</dfn>
are to return the result of running <a>get an attribute value</a> given the associated
<a for=/>element</a> and the associated <a>attribute</a>'s <a for=Attr>local name</a>.</p>

<hr>

<p>A {{DOMTokenList}} object has these <a>attribute change steps</a> for its associated
<a for=/>element</a>:

<ol>
 <li><p>If <var>localName</var> is associated attribute's <a for=Attr>local name</a>,
 <var>namespace</var> is null, and <var>value</var> is null, then <a for=set>empty</a>
 <a>token set</a>.

 <li><p>Otherwise, if <var>localName</var> is associated attribute's <a for=Attr>local name</a>,
 <var>namespace</var> is null, then set <a>token set</a> to <var>value</var>,
 <a lt="ordered set parser">parsed</a>.
</ol>

<p>When a {{DOMTokenList}} object is created, then:

<ol>
 <li><p>Let <var>element</var> be associated <a for=/>element</a>.

 <li><p>Let <var>localName</var> be associated attribute's <a for=Attr>local name</a>.

 <li><p>Let <var>value</var> be the result of
 <a lt="get an attribute value">getting an attribute value</a> given <var>element</var> and
 <var>localName</var>.

 <li><p>Run the <a>attribute change steps</a> for <var>element</var>, <var>localName</var>,
 <var>value</var>, <var>value</var>, and null.
</ol>

<dl class="domintro">
 <dt><code><var>tokenlist</var> . {{DOMTokenList/length}}</code>
 <dd><p>Returns the number of tokens.

 <dt><code><var>tokenlist</var> . {{DOMTokenList/item(index)}}</code>
 <dt><code><var>tokenlist</var>[<var>index</var>]</code>
 <dd><p>Returns the token with index <var>index</var>.

 <dt><code><var>tokenlist</var> . {{DOMTokenList/contains(token)}}</code>
 <dd><p>Returns true if <var>token</var> is present, and false otherwise.

 <dt><code><var>tokenlist</var> . <a for=DOMTokenList lt="add()">add(<var>tokens</var>&hellip;)</a></code>
 <dd>
  <p>Adds all arguments passed, except those already present.
  <p>Throws a "{{SyntaxError!!exception}}" {{DOMException}} if one of the arguments is the empty
  string.
  <p>Throws an "{{InvalidCharacterError!!exception}}" {{DOMException}} if one of the arguments
  contains any <a>ASCII whitespace</a>.

 <dt><code><var>tokenlist</var> . <a for=DOMTokenList lt="remove()">remove(<var>tokens</var>&hellip;)</a></code>
 <dd>
  <p>Removes arguments passed, if they are present.
  <p>Throws a "{{SyntaxError!!exception}}" {{DOMException}} if one of the arguments is the empty
  string.
  <p>Throws an "{{InvalidCharacterError!!exception}}" {{DOMException}} if one of the arguments
  contains any <a>ASCII whitespace</a>.

 <dt><code><var>tokenlist</var> . <a method for=DOMTokenList lt="toggle()">toggle(<var>token</var> [, <var>force</var>])</a></code>
 <dd>
  <p>If <var>force</var> is not given, "toggles" <var>token</var>, removing it if it's present and
  adding it if it's not present. If <var>force</var> is true, adds <var>token</var>
  (same as {{add()}}). If <var>force</var> is false, removes <var>token</var> (same
  as {{DOMTokenList/remove()}}).
  <p>Returns true if <var>token</var> is now present, and false otherwise.
  <p>Throws a "{{SyntaxError!!exception}}" {{DOMException}} if <var>token</var> is empty.
  <p>Throws an "{{InvalidCharacterError!!exception}}" {{DOMException}} if <var>token</var> contains
  any spaces.

 <dt><code><var>tokenlist</var> . <a method for=DOMTokenList lt=replace()>replace(<var>token</var>, <var>newToken</var>)</a></code>
 <dd>
  <p>Replaces <var>token</var> with <var>newToken</var>.
  <p>Returns true if <var>token</var> was replaced with <var>newToken</var>, and false otherwise.
  <p>Throws a "{{SyntaxError!!exception}}" {{DOMException}} if one of the arguments is the empty
  string.
  <p>Throws an "{{InvalidCharacterError!!exception}}" {{DOMException}} if one of the arguments
  contains any <a>ASCII whitespace</a>.

 <dt><code><var>tokenlist</var> . <a method for=DOMTokenList lt="supports()">supports(<var>token</var>)</a></code>
 <dd>
  <p>Returns true if <var>token</var> is in the associated attribute's supported tokens. Returns
  false otherwise.
  <p>Throws a <code>TypeError</code> if the associated attribute has no supported tokens defined.

 <dt><code><var>tokenlist</var> . {{DOMTokenList/value}}</code>
 <dd>
  <p>Returns the associated set as string.
  <p>Can be set, to change the associated attribute.
</dl>

<p>The <dfn attribute for=DOMTokenList><code>length</code></dfn> attribute' getter must return
<a>context object</a>'s <a>token set</a>'s <a for=set>size</a>.

<p>The object's <a>supported property indices</a> are the numbers in the range zero to object's
<a>token set</a>'s <a for=set>size</a> minus one, unless <a>token set</a> <a for=set>is empty</a>,
in which case there are no <a>supported property indices</a>.

<p>The <dfn method for="DOMTokenList"><code>item(<var>index</var>)</code></dfn> method, when
invoked, must run these steps:

<ol>
 <li><p>If <var>index</var> is equal to or greater than <a>context object</a>'s <a>token set</a>'s
 <a for=set>size</a>, then return null.

 <li><p>Return <a>context object</a>'s <a>token set</a>[<var>index</var>].
</ol>

<p>The <dfn method for="DOMTokenList"><code>contains(<var>token</var>)</code></dfn> method, when
invoked, must return true if <a>context object</a>'s <a>token set</a>[<var>token</var>]
<a for=set>exists</a>, and false otherwise.</p>

<p>The
<dfn method for="DOMTokenList" lt="add(tokens)|add()"><code>add(<var>tokens</var>&hellip;)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li>
  <p><a for=list>For each</a> <var>token</var> in <var>tokens</var>:

  <ol>
   <li><p>If <var>token</var> is the empty string, then <a>throw</a> a "{{SyntaxError!!exception}}"
   {{DOMException}}.

   <li><p>If <var>token</var> contains any <a>ASCII whitespace</a>, then <a>throw</a> an
   "{{InvalidCharacterError!!exception}}" {{DOMException}}.
  </ol>

 <li><p><a for=list>For each</a> <var>token</var> in <var>tokens</var>, <a for=set>append</a>
 <var>token</var> to <a>context object</a>'s <a>token set</a>.

 <li><p>Run the <a>update steps</a>.
</ol>

<p>The
<dfn method for="DOMTokenList" lt="remove(tokens)|remove()"><code>remove(<var>tokens</var>&hellip;)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li>
  <p><a for=list>For each</a> <var>token</var> in <var>tokens</var>:

  <ol>
   <li><p>If <var>token</var> is the empty string, then <a>throw</a> a "{{SyntaxError!!exception}}"
   {{DOMException}}.

   <li><p>If <var>token</var> contains any <a>ASCII whitespace</a>, then <a>throw</a> an
   "{{InvalidCharacterError!!exception}}" {{DOMException}}.
  </ol>

 <li><p>For each <var>token</var> in <var>tokens</var>, <a for=set>remove</a> <var>token</var> from
 <a>context object</a>'s <a>token set</a>.

 <li><p>Run the <a>update steps</a>.
</ol>

<p>The <dfn method for=DOMTokenList><code>toggle(<var>token</var>, <var>force</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li><p>If <var>token</var> is the empty string, then <a>throw</a> a "{{SyntaxError!!exception}}"
 {{DOMException}}.

 <li><p>If <var>token</var> contains any <a>ASCII whitespace</a>, then <a>throw</a> an
 "{{InvalidCharacterError!!exception}}" {{DOMException}}.

 <li>
  <p>If <a>context object</a>'s <a>token set</a>[<var>token</var>] <a for=set>exists</a>, then:

  <ol>
   <li><p>If <var>force</var> is either not given or is false, then <a for=set>remove</a>
   <var>token</var> from <a>context object</a>'s <a>token set</a>, run the <a>update steps</a> and
   return false.

   <li><p>Return true.
  </ol>

 <li><p>Otherwise, if <var>force</var> not given or is true, <a for=set>append</a> <var>token</var>
 to <a>context object</a>'s <a>token set</a>, run the <a>update steps</a>, and return true.

 <li><p>Return false.
</ol>

<p class="note no-backref">The <a>update steps</a> are not always run for {{DOMTokenList/toggle()}}
for web compatibility.

<p>The
<dfn method for=DOMTokenList><code>replace(<var>token</var>, <var>newToken</var>)</code></dfn>
method, when invoked, must run these steps:
<!-- Argument order based on String.prototype.replace(), not replaceChild() -->

<ol>
 <li><p>If either <var>token</var> or <var>newToken</var> is the empty string, then <a>throw</a> a
 "{{SyntaxError!!exception}}" {{DOMException}}.

 <li><p>If either <var>token</var> or <var>newToken</var> contains any <a>ASCII whitespace</a>, then
 <a>throw</a> an "{{InvalidCharacterError!!exception}}" {{DOMException}}.

 <li><p>If <a>context object</a>'s <a>token set</a> does not <a for=set>contain</a>
 <var>token</var>, then return false.</p>

 <li><p><a for=set>Replace</a> <var>token</var> in <a>context object</a>'s <a>token set</a> with
 <var>newToken</var>.

 <li><p>Run the <a>update steps</a>.

 <li><p>Return true.
</ol>

<p class="note no-backref">The <a>update steps</a> are not always run for {{DOMTokenList/replace()}}
for web compatibility.

<p>The
<dfn method for="DOMTokenList" lt="supports(token)"><code>supports(<var>token</var>)</code></dfn>
method, when invoked, must run these steps:

<ol>
 <li><p>Let <var>result</var> be the return value of <a>validation steps</a> called with
 <var>token</var>.

 <li><p>Return <var>result</var>.
</ol>

<p>The <dfn attribute for=DOMTokenList><code>value</code></dfn> attribute must return the
result of running <a>context object</a>'s <a>serialize steps</a>.

<p>Setting the {{DOMTokenList/value}} attribute must <a>set an attribute value</a> for the
associated <a for="/">element</a> using associated <a>attribute</a>'s <a for=Attr>local name</a> and
the given value.



<h2 id=xpath>XPath</h2>

<p class=XXX><cite>DOM Level 3 XPath</cite> defined an API for evaluating <cite>XPath 1.0</cite>
expressions. These APIs are widely implemented, but have not been maintained. The interface
definitions are maintained here so that they can be updated when <cite>Web IDL</cite> changes.
Complete definitions of these APIs remain necessary and such work is tracked and can be contributed
to in <a href="https://github.com/whatwg/dom/issues/67">whatwg/dom#67</a>. [[DOM-Level-3-XPath]]
[[XPath]] [[WEBIDL]]


<h3 id=interface-xpathresult>Interface {{XPathResult}}</h3>

<pre class=idl>
[Exposed=Window]
interface XPathResult {
  const unsigned short ANY_TYPE = 0;
  const unsigned short NUMBER_TYPE = 1;
  const unsigned short STRING_TYPE = 2;
  const unsigned short BOOLEAN_TYPE = 3;
  const unsigned short UNORDERED_NODE_ITERATOR_TYPE = 4;
  const unsigned short ORDERED_NODE_ITERATOR_TYPE = 5;
  const unsigned short UNORDERED_NODE_SNAPSHOT_TYPE = 6;
  const unsigned short ORDERED_NODE_SNAPSHOT_TYPE = 7;
  const unsigned short ANY_UNORDERED_NODE_TYPE = 8;
  const unsigned short FIRST_ORDERED_NODE_TYPE = 9;

  readonly attribute unsigned short resultType;
  readonly attribute unrestricted double numberValue;
  readonly attribute DOMString stringValue;
  readonly attribute boolean booleanValue;
  readonly attribute Node? singleNodeValue;
  readonly attribute boolean invalidIteratorState;
  readonly attribute unsigned long snapshotLength;

  Node? iterateNext();
  Node? snapshotItem(unsigned long index);
};
</pre>


<h3 id=interface-xpathexpression>Interface {{XPathExpression}}</h3>

<pre class=idl>
[Exposed=Window]
interface XPathExpression {
  // XPathResult.ANY_TYPE = 0
  XPathResult evaluate(Node contextNode, optional unsigned short type = 0, optional XPathResult? result = null);
};
</pre>


<h3 id=mixin-xpathevaluatorbase>Mixin {{XPathEvaluatorBase}}</h3>

<pre class=idl>
callback interface XPathNSResolver {
  DOMString? lookupNamespaceURI(DOMString? prefix);
};

interface mixin XPathEvaluatorBase {
  [NewObject] XPathExpression createExpression(DOMString expression, optional XPathNSResolver? resolver = null);
  XPathNSResolver createNSResolver(Node nodeResolver);
  // XPathResult.ANY_TYPE = 0
  XPathResult evaluate(DOMString expression, Node contextNode, optional XPathNSResolver? resolver = null, optional unsigned short type = 0, optional XPathResult? result = null);
};
Document includes XPathEvaluatorBase;
</pre>


<h3 id=interface-xpathevaluator>Interface {{XPathEvaluator}}</h3>

<pre class=idl>
[Exposed=Window]
interface XPathEvaluator {
  constructor();
};

XPathEvaluator includes XPathEvaluatorBase;
</pre>

<p class=note>For historical reasons you can both construct {{XPathEvaluator}} and access the same
methods on {{Document}}.



<h2 id=historical>Historical</h2>

<p>As explained in <a href="#goals">goals</a> this standard is a significant revision of various
obsolete DOM specifications. This section enumerates the incompatible changes.


<h3 id=dom-events-changes>DOM Events</h3>

<p>These are the changes made to the features described in the "DOM Event Architecture",
"Basic Event Interfaces", "Mutation Events", and "Mutation Name Event Types" chapters of
<cite>DOM Level 3 Events</cite>. The other chapters are defined by the <cite>UI Events</cite>
specification. [[!UIEVENTS]]

<ul class=brief>
 <li>Removes <dfn interface>MutationEvent</dfn> and <dfn interface>MutationNameEvent</dfn>.
 <li>Fire is no longer synonymous with dispatch, but includes initializing an event.
 <li>The propagation and canceled flags are unset when invoking {{Event/initEvent()}} rather than
 after dispatch.
 <li>{{Event}}'s {{Event/timeStamp}} attribute is a {{DOMHighResTimeStamp}} rather than a
 {{DOMTimeStamp}}.
</ul>


<h3 id=dom-core-changes>DOM Core</h3>

<p>These are the changes made to the features described in <cite>DOM Level 3 Core</cite>.

<p>{{DOMString}}, {{DOMException}}, and {{DOMTimeStamp}} are now defined in Web IDL.

<p id=domstringlist>{{DOMStringList}} is now defined in HTML.

<p><dfn method for=Node><code>hasAttributes()</code></dfn> and
<dfn attribute for=Node><code>attributes</code></dfn> moved from {{Node}} to {{Element}}.

<p><dfn attribute for=Node><code>namespaceURI</code></dfn>,
<dfn attribute for=Node><code>prefix</code></dfn>, and
<dfn attribute for=Node><code>localName</code></dfn> moved from {{Node}} to {{Element}} and
{{Attr}}.

<p>The remainder of interfaces and interface members listed in this section were removed to simplify
the web platform. Implementations conforming to this specification will not support them.

<p>Interfaces:

<ul class=brief dfn-type="interface">
 <li><dfn><code>DOMConfiguration</code></dfn>
 <li><dfn><code>DOMError</code></dfn>
 <li><dfn><code>DOMErrorHandler</code></dfn>
 <li><dfn><code>DOMImplementationList</code></dfn>
 <li><dfn><code>DOMImplementationSource</code></dfn>
 <li><dfn><code>DOMLocator</code></dfn>
 <li><dfn><code>DOMObject</code></dfn>
 <li><dfn><code>DOMUserData</code></dfn>
 <li><dfn><code>Entity</code></dfn>
 <li><dfn><code>EntityReference</code></dfn>
 <li><dfn><code>NameList</code></dfn>
 <li><dfn><code>Notation</code></dfn>
 <li><dfn><code>TypeInfo</code></dfn>
 <li><dfn><code>UserDataHandler</code></dfn>
</ul>

<p>Interface members:

<dl>
 <dt>{{Node}}
 <dd>
  <ul class=brief>
   <li><dfn attribute for=Node><code>isSupported</code></dfn>
   <li><dfn method for=Node><code>getFeature()</code></dfn>
   <li><dfn method for=Node><code>getUserData()</code></dfn>
   <li><dfn method for=Node><code>setUserData()</code></dfn>
  </ul>

 <dt>{{Document}}
 <dd>
  <ul class=brief>
   <li><dfn method for=Document><code>createEntityReference()</code></dfn>
   <li><dfn attribute for=Document><code>xmlEncoding</code></dfn>
   <li><dfn attribute for=Document><code>xmlStandalone</code></dfn>
   <li><dfn attribute for=Document><code>xmlVersion</code></dfn>
   <li><dfn attribute for=Document><code>strictErrorChecking</code></dfn>
   <li><dfn attribute for=Document><code>domConfig</code></dfn>
   <li><dfn method for=Document><code>normalizeDocument()</code></dfn>
   <li><dfn method for=Document><code>renameNode()</code></dfn>
  </ul>

 <dt>{{DOMImplementation}}
 <dd>
  <ul class=brief>
   <li><dfn method for=DOMImplementation><code>getFeature()</code></dfn>
  </ul>

 <dt>{{Attr}}
 <dd>
  <ul class=brief>
   <li><dfn attribute for=Attr><code>schemaTypeInfo</code></dfn>
   <li><dfn attribute for=Attr><code>isId</code></dfn>
  </ul>

 <dt>{{Element}}
 <dd>
  <ul class=brief>
   <li><dfn attribute for=Element><code>schemaTypeInfo</code></dfn>
   <li><dfn method for=Element><code>setIdAttribute()</code></dfn>
   <li><dfn method for=Element><code>setIdAttributeNS()</code></dfn>
   <li><dfn method for=Element><code>setIdAttributeNode()</code></dfn>
  </ul>

 <dt>{{DocumentType}}
 <dd>
  <ul class=brief>
   <li><dfn attribute for=DocumentType><code>entities</code></dfn>
   <li><dfn attribute for=DocumentType><code>notations</code></dfn>
   <li><dfn attribute for=DocumentType><code>internalSubset</code></dfn>
  </ul>

 <dt>{{Text}}
 <dd>
  <ul class=brief>
   <li><dfn attribute for=Text><code>isElementContentWhitespace</code></dfn>
   <li><dfn method for=Text><code>replaceWholeText()</code></dfn>
  </ul>
</dl>


<h3 id=dom-ranges-changes>DOM Ranges</h3>

<p>These are the changes made to the features described in the "Document Object Model Range" chapter
of <cite>DOM Level 2 Traversal and Range</cite>.

<ul class=brief>
 <li><dfn interface>RangeException</dfn> has been removed.
 <li>{{Range/detach()}} is now a no-op.
</ul>


<h3 id=dom-traversal-changes>DOM Traversal</h3>

<p>These are the changes made to the features described in the "Document Object Model Traversal"
chapter of <cite>DOM Level 2 Traversal and Range</cite>.

<ul class=brief>
 <li>{{createNodeIterator()}} and {{createTreeWalker()}} now have optional arguments and lack a
 fourth argument which is no longer relevant given entity references never made it into the DOM.
 <li>The <dfn for="NodeIterator, TreeWalker" attribute>expandEntityReferences</dfn> attribute has
 been removed from the {{NodeIterator}} and {{TreeWalker}} interfaces for the aforementioned reason.
 <li>{{NodeIterator/nextNode()}} and {{NodeIterator/previousNode()}} now throw when invoked from a
 {{NodeFilter}} to align with user agents.
 <li>{{NodeIterator/detach()}} is now a no-op.
</ul>


<h2 class=no-num id="acks">Acknowledgments</h2>

<p>There have been a lot of people that have helped make DOM more interoperable over the years and
thereby furthered the goals of this standard. Likewise many people have helped making this standard
what it is today.

<p>With that, many thanks to
Adam Klein,
Adrian Bateman,
Aleksey Shvayka,
Alex Komoroske,
Alex Russell,
Anthony Ramine,
Arkadiusz Michalski,
Arnaud Le Hors,
Arun Ranganathan,
Björn Höhrmann,
Boris Zbarsky,
Brandon Payton,
Brandon Slade,
Brandon Wallace,
Brian Kardell,
Cameron McCormack,
Chris Dumez,
Chris Paris,
Chris Rebert,
Cyrille Tuzi,
Daniel Glazman,
Darin Fisher,
David Bruant,
David Flanagan,
David Håsäther,
David Hyatt,
Deepak Sherveghar,
Dethe Elza,
Dimitri Glazkov,
Domenic Denicola,
Dominic Cooney,
Dominique Hazaël-Massieux,
Don Jordan,
Doug Schepers,
Edgar Chen,
Elisée Maurer,
Elliott Sprehn,
Emilio Cobos Álvarez,
Eric Bidelman,
Erik Arvidsson,
Gary Kacmarcik,
Gavin Nicol,
Giorgio Liscio,
Glen Huang,
Glenn Adams,
Glenn Maynard,
Hajime Morrita,
Harald Alvestrand,
Hayato Ito,
Henri Sivonen,
Hongchan Choi,
Hunan Rostomyan,
Ian Hickson,
Igor Bukanov,
Jacob Rossi,
Jake Archibald<!-- technically B.J. Archibald -->,
Jake Verbaten,
James Graham,
James Greene,
James Robinson,
Jeffrey Yasskin,
Jens Lindström,
Jesse McCarthy,
Jinho Bang,
João Eiras,
Joe Kesselman,
John Atkins,
John Dai,
Jonas Sicking,
Jonathan Kingston,
Jonathan Robie,
Joris van der Wel,
Joshua Bell,
J. S. Choi,
Jungkee Song,
Justin Summerlin,
呂康豪 (Kang-Hao Lu),
田村健人 (Kent TAMURA),
Kevin Sweeney,
Kirill Topolyan,
Koji Ishii,
Lachlan Hunt,
Lauren Wood,
Luke Zielinski,
Magne Andersson,
Majid Valipour,
Malte Ubl,
Manish Goregaokar,
Manish Tripathi,
Marcos Caceres,
Mark Miller,
Martijn van der Ven,
Mats Palmgren,
Mounir Lamouri,
Michael Stramel,
Michael™ Smith,
Mike Champion,
Mike Taylor,
Mike West,
Ojan Vafai,
Oliver Nightingale,
Olli Pettay,
Ondřej Žára,
Peter Sharpe,
Philip Jägenstedt,
Philippe Le Hégaret,
Piers Wombwell,
Pierre-Marie Dartus,
prosody—Gab<!-- riel --> Vereable<!-- Gaston --> <!-- Croft -->Context(,
Ra'Shaun Stovall (Snuggs),
Rafael Weinstein,
Rakina Zata Amni,
Richard Bradshaw,
Rick Byers,
Rick Waldron,
Robbert Broersma,
Robin Berjon,
Roland Steiner,
Rune <span title=Fabulous>F.</span> Halvorsen,
Russell Bicknell,
Ruud Steltenpool,
Ryosuke Niwa,
Sam Dutton,
Sam Sneddon,
Samuel Giles,
Sanket Joshi,
Sebastian Mayr,
Seo Sanghyeon,
Sergey G. Grekhov,
Shiki Okasaka,
Shinya Kawanaka,
Simon Pieters,
Stef Busking,
Steve Byrne,
Stig Halvorsen,
Tab Atkins,
Takashi Sakamoto,
Takayoshi Kochi,
Theresa O'Connor,
Theodore Dubois,
<i>timeless</i>,
Timo Tijhof,
Tobie Langel,
Tom Pixley,
Travis Leithead,
Trevor Rowbotham,
<i>triple-underscore</i>,<!--GitHub-->
Veli Şenol,
Vidur Apparao,
Warren He,
Xidorn Quan,
Yehuda Katz,
Yoav Weiss,
Yoichi Osato,
Yoshinori Sano, and
Zack Weinberg
for being awesome!

<p>This standard is written by <a lang=nl href=https://annevankesteren.nl/>Anne van Kesteren</a>
(<a href=https://www.mozilla.org/>Mozilla</a>, <a href=mailto:annevk@annevk.nl>annevk@annevk.nl</a>)
with substantial contributions from Aryeh Gregor (<a href=mailto:ayg@aryeh.name>ayg@aryeh.name</a>)
and Ms2ger (<a href="mailto:ms2ger@gmail.com">ms2ger@gmail.com</a>).

<p>Part of the revision history of the integration points related to <a for=Element>custom</a>
elements can be found in
<a href="https://github.com/w3c/webcomponents">the w3c/webcomponents repository</a>, which is
available under the
<a href="https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document">W3C Permissive Document License</a>.

<!-- vim: set expandtab shiftwidth=1 tabstop=1 textwidth=100 -->
